|
Lines 12-3488
Link Here
|
| 12 |
PURPOSE. See the above copyright notice for more information. |
12 |
PURPOSE. See the above copyright notice for more information. |
| 13 |
|
13 |
|
| 14 |
=========================================================================*/ |
14 |
=========================================================================*/ |
| 15 |
// Thanks to Terry Jordan of SAIC at the National Energy |
15 |
// Thanks to Terry Jordan of SAIC at the National Energy |
| 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 |
|
| 28 |
// version 2008-07-26 |
| 29 |
|
| 30 |
// Hijack the CRC routine of zlib to omit CRC check for gzipped files |
| 31 |
// (on OSes other than Windows where the mechanism doesn't work due |
| 32 |
// to pre-bound DLL symbols) if set to 1, or not (set to 0). Affects |
| 33 |
// performance by about 3% - 4%. |
| 34 |
#define VTK_FOAMFILE_OMIT_CRCCHECK 1 |
| 35 |
|
| 36 |
// The input/output buffer sizes for zlib in bytes. |
| 37 |
#define VTK_FOAMFILE_INBUFSIZE (16384) |
| 38 |
#define VTK_FOAMFILE_OUTBUFSIZE (131072) |
| 39 |
#define VTK_FOAMFILE_INCLUDE_STACK_SIZE (10) |
| 40 |
|
| 41 |
#if defined(_MSC_VER) && (_MSC_VER >= 1400) |
| 42 |
#define _CRT_SECURE_NO_WARNINGS 1 |
| 43 |
#endif |
| 44 |
|
| 45 |
#if VTK_FOAMFILE_OMIT_CRCCHECK |
| 46 |
#define ZLIB_INTERNAL |
| 47 |
#endif |
| 48 |
|
| 49 |
// for possible future extension of linehead-aware directives |
| 50 |
#define VTK_FOAMFILE_RECOGNIZE_LINEHEAD 0 |
| 51 |
|
| 19 |
#include "vtkOpenFOAMReader.h" |
52 |
#include "vtkOpenFOAMReader.h" |
| 20 |
|
53 |
|
| 21 |
#include <vtkstd/string> |
|
|
| 22 |
#include <vtkstd/vector> |
54 |
#include <vtkstd/vector> |
| 23 |
#include <vtksys/ios/sstream> |
55 |
#include <vtksys/ios/sstream> |
|
|
56 |
#include <vtk_zlib.h> |
| 24 |
|
57 |
|
| 25 |
#include "vtkInformation.h" |
58 |
#include "vtkCallbackCommand.h" |
| 26 |
#include "vtkInformationVector.h" |
|
|
| 27 |
#include "vtkErrorCode.h" |
| 28 |
#include "vtkDataArraySelection.h" |
| 29 |
#include "vtkStreamingDemandDrivenPipeline.h" |
| 30 |
#include "vtkCellArray.h" |
59 |
#include "vtkCellArray.h" |
|
|
60 |
#include "vtkCellData.h" |
| 61 |
#include "vtkCharArray.h" |
| 62 |
#include "vtkConvexPointSet.h" |
| 31 |
#include "vtkDataArraySelection.h" |
63 |
#include "vtkDataArraySelection.h" |
| 32 |
#include "vtkIntArray.h" |
64 |
#include "vtkDirectory.h" |
| 33 |
#include "vtkFloatArray.h" |
|
|
| 34 |
#include "vtkDoubleArray.h" |
65 |
#include "vtkDoubleArray.h" |
| 35 |
#include "vtkPoints.h" |
66 |
#include "vtkFloatArray.h" |
| 36 |
#include "vtkCellData.h" |
|
|
| 37 |
#include "vtkHexahedron.h" |
67 |
#include "vtkHexahedron.h" |
| 38 |
#include "vtkWedge.h" |
68 |
#include "vtkInformation.h" |
|
|
69 |
#include "vtkInformationVector.h" |
| 70 |
#include "vtkIntArray.h" |
| 71 |
#include "vtkMultiBlockDataSet.h" |
| 72 |
#include "vtkObjectFactory.h" |
| 73 |
#include "vtkPointData.h" |
| 74 |
#include "vtkPoints.h" |
| 75 |
#include "vtkPolyData.h" |
| 76 |
#include "vtkPolygon.h" |
| 39 |
#include "vtkPyramid.h" |
77 |
#include "vtkPyramid.h" |
| 40 |
#include "vtkVertex.h" |
78 |
#include "vtkQuad.h" |
|
|
79 |
#include "vtkSmartPointer.h" |
| 80 |
#include "vtkSortDataArray.h" |
| 81 |
#include "vtkStdString.h" |
| 82 |
#include "vtkStreamingDemandDrivenPipeline.h" |
| 83 |
#include "vtkStringArray.h" |
| 41 |
#include "vtkTetra.h" |
84 |
#include "vtkTetra.h" |
| 42 |
#include "vtkConvexPointSet.h" |
|
|
| 43 |
#include "vtkTriangle.h" |
85 |
#include "vtkTriangle.h" |
| 44 |
#include "vtkQuad.h" |
|
|
| 45 |
#include "vtkPolygon.h" |
| 46 |
#include "vtkUnstructuredGrid.h" |
86 |
#include "vtkUnstructuredGrid.h" |
| 47 |
#include "vtkMultiBlockDataSet.h" |
87 |
#include "vtkVertex.h" |
| 48 |
#include "vtkUnstructuredGridAlgorithm.h" |
88 |
#include "vtkWedge.h" |
| 49 |
#include "vtkObjectFactory.h" |
89 |
#if PARAVIEW_VERSION_MAJOR >= 3 && PARAVIEW_VERSION_MINOR >= 3 |
| 50 |
#include "vtkDirectory.h" |
90 |
#include "vtksys/DateStamp.h" |
| 51 |
|
91 |
#endif |
| 52 |
#include <ctype.h> |
|
|
| 53 |
#include <sys/stat.h> |
| 54 |
|
92 |
|
| 55 |
#ifdef VTK_USE_ANSI_STDLIB |
93 |
#if !(defined(_WIN32) && !defined(__CYGWIN__) || defined(__LIBCATAMOUNT__)) |
| 56 |
#define VTK_IOS_NOCREATE |
94 |
// for getpwnam() / getpwuid() |
| 57 |
#else |
95 |
#include <sys/types.h> |
| 58 |
#define VTK_IOS_NOCREATE | ios::nocreate |
96 |
#include <pwd.h> |
|
|
97 |
// for getuid() |
| 98 |
#include <unistd.h> |
| 59 |
#endif |
99 |
#endif |
|
|
100 |
// for fabs() |
| 101 |
#include <math.h> |
| 60 |
|
102 |
|
| 61 |
vtkCxxRevisionMacro(vtkOpenFOAMReader, "$Revision: 1.12 $"); |
103 |
vtkCxxRevisionMacro(vtkOpenFOAMReader, "$Revision: 1.7.2.2 $"); |
| 62 |
vtkStandardNewMacro(vtkOpenFOAMReader); |
104 |
vtkStandardNewMacro(vtkOpenFOAMReader); |
| 63 |
|
105 |
|
| 64 |
struct stdString |
106 |
#if VTK_FOAMFILE_OMIT_CRCCHECK |
|
|
107 |
uLong ZEXPORT crc32(uLong, const Bytef *, uInt) |
| 108 |
{ return 0; } |
| 109 |
#endif |
| 110 |
|
| 111 |
template<typename T> class objectVector: public vtkstd::vector<T> |
| 65 |
{ |
112 |
{ |
| 66 |
vtkstd::string value; |
113 |
typedef vtkstd::vector<T> Superclass; |
|
|
114 |
|
| 115 |
public: |
| 116 |
~objectVector() |
| 117 |
{ |
| 118 |
for(size_t arrayI = 0; arrayI < Superclass::size(); arrayI++) |
| 119 |
{ |
| 120 |
if(Superclass::operator[](arrayI) != NULL) |
| 121 |
{ |
| 122 |
Superclass::operator[](arrayI)->Delete(); |
| 123 |
} |
| 124 |
} |
| 125 |
} |
| 67 |
}; |
126 |
}; |
| 68 |
|
127 |
|
| 69 |
struct stringVector |
128 |
class intArrayVector: public objectVector<vtkIntArray*> {}; |
|
|
129 |
class unstructuredGridVector: public objectVector<vtkUnstructuredGrid*> {}; |
| 130 |
typedef objectVector<vtkPolyData*> polyDataVector; |
| 131 |
typedef objectVector<vtkStringArray*> stringArrayVector; |
| 132 |
|
| 133 |
struct vtkOpenFOAMReader::intVectorVector |
| 70 |
{ |
134 |
{ |
| 71 |
vtkstd::vector< vtkstd::string > value; |
135 |
private: |
|
|
136 |
vtkIntArray *body_, *indices_; |
| 137 |
int nElements_; |
| 138 |
void clear() { indices_->Delete(); body_->Delete(); } |
| 139 |
intVectorVector(); |
| 140 |
|
| 141 |
public: |
| 142 |
intVectorVector(const intVectorVector &ivv) |
| 143 |
: body_(vtkIntArray::New()), indices_(vtkIntArray::New()), |
| 144 |
nElements_(ivv.nElements_) |
| 145 |
{ |
| 146 |
indices_->DeepCopy(ivv.indices_); // vtkDataArrays do not have ShallowCopy |
| 147 |
body_->DeepCopy(ivv.body_); |
| 148 |
} |
| 149 |
intVectorVector(const int nElements, const int bodyLength) |
| 150 |
: body_(vtkIntArray::New()), indices_(vtkIntArray::New()), |
| 151 |
nElements_(nElements) |
| 152 |
{ |
| 153 |
indices_->SetNumberOfValues(nElements + 1); |
| 154 |
body_->SetNumberOfValues(bodyLength); |
| 155 |
} |
| 156 |
|
| 157 |
~intVectorVector() { clear(); } |
| 158 |
|
| 159 |
// GetSize() returns all allocated size (Size) while GetDataSize() |
| 160 |
// returns actually used size (MaxId * nComponents) |
| 161 |
int bodySize() const { return body_->GetSize(); } |
| 162 |
// note that vtkIntArray::Resize() allocates (current size + new |
| 163 |
// size) bytes if current size < new size |
| 164 |
void resizeBody(const int bodyLength) { body_->Resize(bodyLength); } |
| 165 |
int *setIndex(const int i, const int bodyI) |
| 166 |
{ return body_->GetPointer(*indices_->GetPointer(i) = bodyI); } |
| 167 |
void setValue(const int bodyI, int value) { body_->SetValue(bodyI, value); } |
| 168 |
const int *operator[](const int i) const |
| 169 |
{ return body_->GetPointer(indices_->GetValue(i)); } |
| 170 |
int size(const int i) const |
| 171 |
{ return indices_->GetValue(i + 1) - indices_->GetValue(i); } |
| 172 |
int nElements() const { return nElements_; } |
| 72 |
}; |
173 |
}; |
| 73 |
|
174 |
|
| 74 |
struct intVector |
175 |
struct vtkFoamBoundaryEntry |
| 75 |
{ |
176 |
{ |
| 76 |
vtkstd::vector< int > value; |
177 |
vtkStdString boundaryName; |
|
|
178 |
int nFaces, startFace, allBoundariesStartFace; |
| 179 |
bool isActive, isPhysicalBoundary; |
| 77 |
}; |
180 |
}; |
| 78 |
|
181 |
|
| 79 |
struct intVectorVector |
182 |
struct vtkOpenFOAMReader::vtkFoamBoundaryDict |
|
|
183 |
: public vtkstd::vector<vtkFoamBoundaryEntry> |
| 80 |
{ |
184 |
{ |
| 81 |
vtkstd::vector< vtkstd::vector< int > > value; |
185 |
// we need to keep the path to time directory where the current mesh |
|
|
186 |
// is read from, since boundaryDict may be accessed multiple times |
| 187 |
// at a timestep for patch selections |
| 188 |
vtkStdString timeDir; |
| 82 |
}; |
189 |
}; |
| 83 |
|
190 |
|
| 84 |
struct faceVectorVector |
191 |
//----------------------------------------------------------------------------- |
|
|
192 |
// class vtkFoamError |
| 193 |
// class for exception-carrying object |
| 194 |
struct vtkOpenFOAMReader::vtkFoamError: public vtkStdString |
| 85 |
{ |
195 |
{ |
| 86 |
vtkstd::vector< vtkstd::vector< face > > value; |
196 |
public: |
|
|
197 |
vtkFoamError(): vtkStdString() {} |
| 198 |
vtkFoamError(const vtkFoamError& e): vtkStdString(e) {} |
| 199 |
~vtkFoamError() {} |
| 200 |
// a super-easy way to make use of operator<<()'s defined in |
| 201 |
// vtksys_ios::ostringstream class |
| 202 |
template <class T> vtkFoamError& operator<<(const T& t) |
| 203 |
{ vtksys_ios::ostringstream os; os << t; operator+=(os.str()); return *this; } |
| 87 |
}; |
204 |
}; |
| 88 |
|
205 |
|
| 89 |
vtkOpenFOAMReader::vtkOpenFOAMReader() |
206 |
//----------------------------------------------------------------------------- |
|
|
207 |
// class vtkFoamToken |
| 208 |
// token class which also works as container for list types |
| 209 |
// - a word token is treated as a string token for simplicity |
| 210 |
// - handles only atomic types. Handling of list types are left to the |
| 211 |
// derived classes. |
| 212 |
struct vtkOpenFOAMReader::vtkFoamToken |
| 90 |
{ |
213 |
{ |
| 91 |
vtkDebugMacro(<<"Constructor"); |
214 |
public: |
| 92 |
this->SetNumberOfInputPorts(0); |
215 |
enum tokenType |
| 93 |
|
216 |
{ |
| 94 |
//INTIALIZE FILE NAME |
217 |
// undefined type |
| 95 |
this->FileName = NULL; |
218 |
UNDEFINED, |
| 96 |
|
219 |
// atomic types |
| 97 |
//VTK CLASSES |
220 |
PUNCTUATION, LABEL, SCALAR, STRING, IDENTIFIER, |
| 98 |
this->Points = vtkPoints::New(); |
221 |
// vtkObject-derived list types |
| 99 |
this->CellDataArraySelection = vtkDataArraySelection::New(); |
222 |
STRINGLIST, LABELLIST, SCALARLIST, VECTORLIST, |
| 100 |
|
223 |
// original list types |
| 101 |
//DATA COUNTS |
224 |
LABELLISTLIST, ENTRYVALUELIST, EMPTYLIST, DICTIONARY, |
| 102 |
this->NumFaces = 0; |
225 |
// exceptional state |
| 103 |
this->NumPoints = 0; |
226 |
UNIFORMLABELLIST, UNIFORMSCALARLIST, |
| 104 |
this->NumCells = 0; |
227 |
// error state |
| 105 |
|
228 |
ERROR |
| 106 |
this->TimeStepData = new stringVector; |
229 |
}; |
| 107 |
this->Path = new stdString; |
230 |
|
| 108 |
this->PathPrefix = new stdString; |
231 |
protected: |
| 109 |
this->PolyMeshPointsDir = new stringVector; |
232 |
tokenType type_; |
| 110 |
this->PolyMeshFacesDir = new stringVector; |
233 |
union |
| 111 |
this->BoundaryNames = new stringVector; |
234 |
{ |
| 112 |
this->PointZoneNames = new stringVector; |
235 |
char char_; |
| 113 |
this->FaceZoneNames = new stringVector; |
236 |
int int_; |
| 114 |
this->CellZoneNames = new stringVector; |
237 |
double double_; |
| 115 |
|
238 |
vtkStdString* string_; |
| 116 |
this->FacePoints = new intVectorVector; |
239 |
vtkObjectBase *vtkObjectPtr_; |
| 117 |
this->FacesOwnerCell = new intVectorVector; |
240 |
// vtkObject-derived list types |
| 118 |
this->FacesNeighborCell = new intVectorVector; |
241 |
vtkIntArray *labelListPtr_; |
| 119 |
this->FacesOfCell = new faceVectorVector; |
242 |
vtkFloatArray *scalarListPtr_, *vectorListPtr_; |
| 120 |
this->SizeOfBoundary = new intVector; |
243 |
vtkStringArray *stringListPtr_; |
| 121 |
|
244 |
// original list types |
| 122 |
//DATA TIMES |
245 |
intVectorVector *labelListListPtr_; |
| 123 |
this->NumberOfTimeSteps = 0; |
246 |
vtkstd::vector<vtkFoamEntryValue*> *entryValuePtrs_; |
| 124 |
this->Steps = NULL; |
247 |
vtkFoamDict *dictPtr_; |
| 125 |
this->TimeStep = 0; |
248 |
}; |
| 126 |
this->TimeStepRange[0] = 0; |
249 |
|
| 127 |
this->TimeStepRange[1] = 0; |
250 |
void clear() |
| 128 |
this->RequestInformationFlag = true; |
251 |
{ |
| 129 |
} |
252 |
if(type_ == STRING || type_ == IDENTIFIER) |
|
|
253 |
{ |
| 254 |
delete string_; |
| 255 |
} |
| 256 |
} |
| 257 |
|
| 258 |
void assignData(const vtkFoamToken& value) |
| 259 |
{ |
| 260 |
switch(value.type_) |
| 261 |
{ |
| 262 |
case PUNCTUATION: |
| 263 |
char_ = value.char_; |
| 264 |
break; |
| 265 |
case LABEL: |
| 266 |
int_ = value.int_; |
| 267 |
break; |
| 268 |
case SCALAR: |
| 269 |
double_ = value.double_; |
| 270 |
break; |
| 271 |
case STRING: case IDENTIFIER: |
| 272 |
string_ = new vtkStdString(*value.string_); |
| 273 |
} |
| 274 |
} |
| 275 |
|
| 276 |
public: |
| 277 |
vtkFoamToken(): type_(UNDEFINED) {} |
| 278 |
vtkFoamToken(const vtkFoamToken& value): type_(value.type_) |
| 279 |
{ assignData(value); } |
| 280 |
~vtkFoamToken() { clear(); } |
| 281 |
|
| 282 |
const tokenType type() const { return type_; } |
| 283 |
|
| 284 |
template<typename T> bool is() const; |
| 285 |
template<typename T> T to() const; |
| 286 |
|
| 287 |
const vtkStdString toString() const { return *string_; } |
| 288 |
const vtkStdString toIdentifier() const { return *string_; } |
| 289 |
|
| 290 |
void setBad() { clear(); type_ = ERROR; } |
| 291 |
void setIdentifier(const vtkStdString& idString) |
| 292 |
{ operator=(idString); type_ = IDENTIFIER; } |
| 293 |
|
| 294 |
void operator=(const char value) |
| 295 |
{ clear(); type_ = PUNCTUATION; char_ = value; } |
| 296 |
void operator=(const int value) |
| 297 |
{ clear(); type_ = LABEL; int_ = value; } |
| 298 |
void operator=(const double value) |
| 299 |
{ clear(); type_ = SCALAR; double_ = value; } |
| 300 |
void operator=(const char *value) |
| 301 |
{ clear(); type_ = STRING; string_ = new vtkStdString(value); } |
| 302 |
void operator=(const vtkStdString& value) |
| 303 |
{ clear(); type_ = STRING; string_ = new vtkStdString(value); } |
| 304 |
void operator=(const vtkFoamToken& value) |
| 305 |
{ clear(); type_ = value.type_; assignData(value); } |
| 306 |
bool operator==(const char value) const |
| 307 |
{ return type_ == PUNCTUATION && char_ == value; } |
| 308 |
bool operator==(const int value) const |
| 309 |
{ return type_ == LABEL && int_ == value; } |
| 310 |
bool operator==(const vtkStdString& value) const |
| 311 |
{ return type_ == STRING && *string_ == value; } |
| 312 |
bool operator!=(const vtkStdString& value) const |
| 313 |
{ return type_ != STRING || *string_ != value; } |
| 314 |
bool operator!=(const char value) const { return !operator==(value); } |
| 315 |
|
| 316 |
friend vtksys_ios::ostringstream& operator<<(vtksys_ios::ostringstream& str, |
| 317 |
const vtkFoamToken& value) |
| 318 |
{ |
| 319 |
switch(value.type()) |
| 320 |
{ |
| 321 |
case ERROR: |
| 322 |
str << "badToken (an unexpected EOF?)"; |
| 323 |
break; |
| 324 |
case PUNCTUATION: |
| 325 |
str << value.char_; |
| 326 |
break; |
| 327 |
case LABEL: |
| 328 |
str << value.int_; |
| 329 |
break; |
| 330 |
case SCALAR: |
| 331 |
str << value.double_; |
| 332 |
break; |
| 333 |
case STRING: case IDENTIFIER: |
| 334 |
str << *value.string_; |
| 335 |
break; |
| 336 |
} |
| 337 |
return str; |
| 338 |
} |
| 339 |
}; |
| 130 |
|
340 |
|
| 131 |
vtkOpenFOAMReader::~vtkOpenFOAMReader() |
341 |
template<> inline bool vtkOpenFOAMReader::vtkFoamToken::is<int>() const |
|
|
342 |
{ return type_ == LABEL; } |
| 343 |
template<> inline bool vtkOpenFOAMReader::vtkFoamToken::is<float>() const |
| 344 |
{ return type_ == LABEL || type_ == SCALAR; } |
| 345 |
template<> inline bool vtkOpenFOAMReader::vtkFoamToken::is<double>() const |
| 346 |
{ return type_ == SCALAR; } |
| 347 |
template<> inline int vtkOpenFOAMReader::vtkFoamToken::to() const |
| 348 |
{ return int_; } |
| 349 |
template<> inline float vtkOpenFOAMReader::vtkFoamToken::to() const |
| 350 |
{ return type_ == LABEL ? int_ : double_; } |
| 351 |
template<> inline double vtkOpenFOAMReader::vtkFoamToken::to() const |
| 352 |
{ return type_ == LABEL ? int_ : double_; } |
| 353 |
|
| 354 |
//----------------------------------------------------------------------------- |
| 355 |
// class vtkFoamFileStack |
| 356 |
// list of variables that have to be saved when a file is included. |
| 357 |
struct vtkOpenFOAMReader::vtkFoamFileStack |
| 132 |
{ |
358 |
{ |
| 133 |
vtkDebugMacro(<<"DeConstructor"); |
359 |
protected: |
| 134 |
this->Points->Delete(); |
360 |
vtkStdString fileName_; |
| 135 |
this->CellDataArraySelection->Delete(); |
361 |
FILE *file_; |
| 136 |
this->SetFileName(0); |
362 |
bool isCompressed_; |
| 137 |
delete [] this->Steps; |
363 |
z_stream z_; |
|
|
364 |
int zStatus_; |
| 365 |
int lineNumber_; |
| 366 |
#if VTK_FOAMFILE_RECOGNIZE_LINEHEAD |
| 367 |
bool wasNewline_; |
| 368 |
#endif |
| 138 |
|
369 |
|
| 139 |
delete this->TimeStepData; |
370 |
// buffer pointers. using raw pointers for performance reason. |
| 140 |
delete this->Path; |
371 |
unsigned char *inbuf_; |
| 141 |
delete this->PathPrefix; |
372 |
unsigned char *outbuf_; |
| 142 |
delete this->PolyMeshPointsDir; |
373 |
unsigned char *bufPtr_; |
| 143 |
delete this->PolyMeshFacesDir; |
374 |
unsigned char *bufEndPtr_; |
| 144 |
delete this->BoundaryNames; |
375 |
|
| 145 |
delete this->PointZoneNames; |
376 |
vtkFoamFileStack() |
| 146 |
delete this->FaceZoneNames; |
377 |
: fileName_(), file_(NULL), isCompressed_(false), zStatus_(Z_OK), |
| 147 |
delete this->CellZoneNames; |
378 |
lineNumber_(0), |
| 148 |
delete this->FacePoints; |
379 |
#if VTK_FOAMFILE_RECOGNIZE_LINEHEAD |
| 149 |
delete this->FacesOwnerCell; |
380 |
wasNewline_(true), |
| 150 |
delete this->FacesNeighborCell; |
381 |
#endif |
| 151 |
delete this->FacesOfCell; |
382 |
inbuf_(NULL), outbuf_(NULL), bufPtr_(NULL), bufEndPtr_(NULL) |
| 152 |
delete this->SizeOfBoundary; |
383 |
{ z_.zalloc = Z_NULL; z_.zfree = Z_NULL; z_.opaque = Z_NULL; } |
| 153 |
} |
|
|
| 154 |
|
384 |
|
| 155 |
int vtkOpenFOAMReader::RequestData( |
385 |
void reset() |
| 156 |
vtkInformation *vtkNotUsed(request), |
386 |
{ |
| 157 |
vtkInformationVector **vtkNotUsed(inputVector), |
387 |
// path_ = ""; |
| 158 |
vtkInformationVector *outputVector) |
388 |
file_ = NULL; |
| 159 |
{ |
389 |
isCompressed_ = false; |
| 160 |
vtkDebugMacro(<<"Request Data"); |
390 |
// zStatus_ = Z_OK; |
| 161 |
vtkInformation* outInfo = outputVector->GetInformationObject(0); |
391 |
z_.zalloc = Z_NULL; |
| 162 |
vtkMultiBlockDataSet *output = vtkMultiBlockDataSet::SafeDownCast( |
392 |
z_.zfree = Z_NULL; |
| 163 |
outInfo->Get(vtkMultiBlockDataSet::DATA_OBJECT())); |
393 |
z_.opaque = Z_NULL; |
| 164 |
if(!this->FileName) |
394 |
// lineNumber_ = 0; |
| 165 |
{ |
395 |
#if VTK_FOAMFILE_RECOGNIZE_LINEHEAD |
| 166 |
vtkErrorMacro("FileName has to be specified!"); |
396 |
wasNewline_ = true; |
| 167 |
return 0; |
397 |
#endif |
| 168 |
} |
|
|
| 169 |
this->CreateDataSet(output); |
| 170 |
return 1; |
| 171 |
} |
| 172 |
|
398 |
|
| 173 |
void vtkOpenFOAMReader::PrintSelf(ostream& os, vtkIndent indent) |
399 |
inbuf_ = NULL; |
| 174 |
{ |
400 |
outbuf_ = NULL; |
| 175 |
vtkDebugMacro(<<"Print Self"); |
401 |
// bufPtr_ = NULL; |
| 176 |
this->Superclass::PrintSelf(os,indent); |
402 |
// bufEndPtr_ = NULL; |
| 177 |
os << indent << "File Name: " |
403 |
} |
| 178 |
<< (this->FileName ? this->FileName : "(none)") << "\n"; |
404 |
|
| 179 |
os << indent << "Number Of Nodes: " << this->NumPoints << "\n"; |
405 |
public: |
| 180 |
os << indent << "Number Of Cells: " << this->NumCells << "\n"; |
406 |
const vtkStdString& fileName() const { return fileName_; } |
| 181 |
os << indent << "Number of Time Steps: " << this->NumberOfTimeSteps << endl; |
407 |
int lineNumber() const { return lineNumber_; } |
| 182 |
os << indent << "TimeStepRange: " |
408 |
}; |
| 183 |
<< this->TimeStepRange[0] << " - " << this->TimeStepRange[1] |
|
|
| 184 |
<< endl; |
| 185 |
os << indent << "TimeStep: " << this->TimeStep << endl; |
| 186 |
return; |
| 187 |
} |
| 188 |
|
409 |
|
| 189 |
int vtkOpenFOAMReader::RequestInformation( |
410 |
//----------------------------------------------------------------------------- |
| 190 |
vtkInformation *vtkNotUsed(request), |
411 |
// class vtkFoamFile |
| 191 |
vtkInformationVector **vtkNotUsed(inputVector), |
412 |
// read and tokenize the input. |
| 192 |
vtkInformationVector *outputVector) |
413 |
struct vtkOpenFOAMReader::vtkFoamFile: public vtkFoamFileStack |
| 193 |
{ |
414 |
{ |
| 194 |
if(!this->FileName) |
415 |
public: |
| 195 |
{ |
416 |
// #inputMode values |
| 196 |
vtkErrorMacro("FileName has to be specified!"); |
417 |
enum inputModes { INPUT_MODE_MERGE, INPUT_MODE_OVERWRITE, INPUT_MODE_ERROR }; |
| 197 |
return 0; |
|
|
| 198 |
} |
| 199 |
vtkDebugMacro(<<"Request Info"); |
| 200 |
if(RequestInformationFlag) |
| 201 |
{ |
| 202 |
vtkDebugMacro(<<this->FileName); |
| 203 |
this->Path->value.append(this->FileName); |
| 204 |
this->ReadControlDict(); |
| 205 |
this->TimeStepRange[0] = 0; |
| 206 |
this->TimeStepRange[1] = this->NumberOfTimeSteps-1; |
| 207 |
this->PopulatePolyMeshDirArrays(); |
| 208 |
outputVector->GetInformationObject(0)->Set( |
| 209 |
vtkStreamingDemandDrivenPipeline::TIME_STEPS(), this->Steps, |
| 210 |
this->NumberOfTimeSteps); |
| 211 |
this->RequestInformationFlag = false; |
| 212 |
} |
| 213 |
|
418 |
|
| 214 |
//Add scalars and vectors to metadata |
419 |
private: |
| 215 |
//create path to current time step |
420 |
bool is13Positions_; |
| 216 |
vtksys_ios::stringstream tempPath; |
421 |
inputModes inputMode_; |
| 217 |
tempPath << this->PathPrefix->value.c_str(); |
|
|
| 218 |
tempPath << this->Steps[this->TimeStep]; |
| 219 |
|
422 |
|
| 220 |
//open the directory and get num of files |
423 |
// inclusion handling |
| 221 |
int numSolvers; |
424 |
vtkFoamFileStack *stack_[VTK_FOAMFILE_INCLUDE_STACK_SIZE]; |
| 222 |
vtkDirectory * directory = vtkDirectory::New(); |
425 |
int stackI_; |
| 223 |
int opened = directory->Open(tempPath.str().c_str()); |
426 |
vtkStdString casePath_; |
| 224 |
if(opened) |
|
|
| 225 |
{ |
| 226 |
numSolvers = directory->GetNumberOfFiles(); |
| 227 |
} |
| 228 |
else |
| 229 |
{ |
| 230 |
numSolvers = -1; //no dir |
| 231 |
} |
| 232 |
|
427 |
|
| 233 |
//clear prior timestep data |
428 |
// declare and define as private |
| 234 |
this->TimeStepData->value.clear(); |
429 |
vtkFoamFile(); |
|
|
430 |
bool inflateNext(unsigned char *buf, int requestSize); |
| 431 |
int nextTokenHead(); |
| 432 |
// hacks to keep exception throwing / recursive codes out-of-line to make |
| 433 |
// putBack(), getc() and readExpecting() inline expandable |
| 434 |
void throwDuplicatedPutBackException(); |
| 435 |
void throwUnexpectedEOFException(); |
| 436 |
void throwUnexpectedNondigitCharExecption(const int c); |
| 437 |
void throwUnexpectedTokenException(const char, const int c); |
| 438 |
int readNext(); |
| 235 |
|
439 |
|
| 236 |
//loop over all files and locate |
440 |
void putBack(const int c) |
| 237 |
//volScalars and volVectors |
441 |
{ |
| 238 |
for(int j = 0; j < numSolvers; j++) |
442 |
if(--bufPtr_ < outbuf_) |
| 239 |
{ |
|
|
| 240 |
const char * tempSolver = directory->GetFile(j); |
| 241 |
if(tempSolver != (char *)"polyMesh") |
| 242 |
{ |
443 |
{ |
| 243 |
if(tempSolver != (char *)"." && tempSolver != (char *)"..") |
444 |
throwDuplicatedPutBackException(); |
| 244 |
{ |
|
|
| 245 |
vtkstd::string type(this->GetDataType(tempPath.str().c_str(), |
| 246 |
tempSolver)); |
| 247 |
if(strcmp(type.c_str(), "Scalar") == 0) |
| 248 |
{ |
| 249 |
this->TimeStepData->value.push_back(vtkstd::string(tempSolver)); |
| 250 |
this->CellDataArraySelection->AddArray(tempSolver); |
| 251 |
} |
| 252 |
else if(strcmp(type.c_str(), "Vector") == 0) |
| 253 |
{ |
| 254 |
this->TimeStepData->value.push_back(vtkstd::string(tempSolver)); |
| 255 |
this->CellDataArraySelection->AddArray(tempSolver); |
| 256 |
} |
| 257 |
} |
| 258 |
} |
445 |
} |
| 259 |
} |
446 |
*bufPtr_ = c; |
| 260 |
|
447 |
} |
| 261 |
directory->Delete(); |
|
|
| 262 |
return 1; |
| 263 |
} |
| 264 |
|
| 265 |
// |
| 266 |
// CELL METHODS |
| 267 |
// |
| 268 |
int vtkOpenFOAMReader::GetNumberOfCellArrays() |
| 269 |
{ |
| 270 |
return this->CellDataArraySelection->GetNumberOfArrays(); |
| 271 |
} |
| 272 |
|
| 273 |
const char* vtkOpenFOAMReader::GetCellArrayName(int index) |
| 274 |
{ |
| 275 |
return this->CellDataArraySelection->GetArrayName(index); |
| 276 |
} |
| 277 |
|
| 278 |
int vtkOpenFOAMReader::GetCellArrayStatus(const char* name) |
| 279 |
{ |
| 280 |
return this->CellDataArraySelection->ArrayIsEnabled(name); |
| 281 |
} |
| 282 |
|
| 283 |
void vtkOpenFOAMReader::SetCellArrayStatus(const char* name, int status) |
| 284 |
{ |
| 285 |
if(status) |
| 286 |
{ |
| 287 |
this->CellDataArraySelection->EnableArray(name); |
| 288 |
} |
| 289 |
else |
| 290 |
{ |
| 291 |
this->CellDataArraySelection->DisableArray(name); |
| 292 |
} |
| 293 |
return; |
| 294 |
} |
| 295 |
|
448 |
|
| 296 |
void vtkOpenFOAMReader::DisableAllCellArrays() |
449 |
// get a character |
| 297 |
{ |
450 |
int getc() { return bufPtr_ == bufEndPtr_ ? readNext() : *bufPtr_++; } |
| 298 |
this->CellDataArraySelection->DisableAllArrays(); |
|
|
| 299 |
return; |
| 300 |
} |
| 301 |
|
451 |
|
| 302 |
void vtkOpenFOAMReader::EnableAllCellArrays() |
452 |
vtkFoamError stackString() |
| 303 |
{ |
453 |
{ |
| 304 |
this->CellDataArraySelection->EnableAllArrays(); |
454 |
vtksys_ios::ostringstream os; |
| 305 |
return; |
455 |
if(stackI_ > 0) |
| 306 |
} |
456 |
{ |
|
|
457 |
os << "\n included"; |
| 307 |
|
458 |
|
| 308 |
// **************************************************************************** |
459 |
for(int stackI = stackI_ - 1; stackI >= 0; stackI--) |
| 309 |
// Method: vtkOpenFOAMReader::CombineOwnerNeigbor |
460 |
{ |
| 310 |
// |
461 |
os << " from line " << stack_[stackI]->lineNumber() << " of " |
| 311 |
// Purpose: |
462 |
<< stack_[stackI]->fileName() << "\n"; |
| 312 |
// add Owner faces to the faces of a cell and then add the neighor faces |
463 |
} |
| 313 |
// |
464 |
os << ": "; |
| 314 |
// **************************************************************************** |
465 |
} |
| 315 |
void vtkOpenFOAMReader::CombineOwnerNeigbor() |
466 |
return vtkFoamError() << os.str(); |
| 316 |
{ |
467 |
} |
| 317 |
vtkDebugMacro(<<"Combine owner & neighbor faces"); |
|
|
| 318 |
//reintialize faces of the cells |
| 319 |
face tempFace; |
| 320 |
this->FacesOfCell->value.clear(); |
| 321 |
this->FacesOfCell->value.resize(this->NumCells); |
| 322 |
|
468 |
|
| 323 |
//add owner faces to cell |
469 |
bool closeIncludedFile() |
| 324 |
for(int i = 0; i < (int)this->FacesOwnerCell->value.size(); i++) |
470 |
{ |
| 325 |
{ |
471 |
if(stackI_ == 0) |
| 326 |
for(int j = 0; j < (int)this->FacesOwnerCell->value[i].size(); j++) |
|
|
| 327 |
{ |
472 |
{ |
| 328 |
tempFace.faceIndex = this->FacesOwnerCell->value[i][j]; |
473 |
return false; |
| 329 |
tempFace.neighborFace = false; |
|
|
| 330 |
this->FacesOfCell->value[i].push_back(tempFace); |
| 331 |
} |
474 |
} |
| 332 |
} |
475 |
clear(); |
|
|
476 |
stackI_--; |
| 477 |
// use the default bitwise assignment operator |
| 478 |
vtkFoamFileStack::operator=(*stack_[stackI_]); |
| 479 |
delete stack_[stackI_]; |
| 480 |
return true; |
| 481 |
} |
| 333 |
|
482 |
|
| 334 |
//add neighbor faces to cell |
483 |
void clear() |
| 335 |
for(int i = 0; i < (int)this->FacesNeighborCell->value.size(); i++) |
484 |
{ |
| 336 |
{ |
485 |
if(isCompressed_) |
| 337 |
for(int j = 0; j < (int)this->FacesNeighborCell->value[i].size(); j++) |
|
|
| 338 |
{ |
486 |
{ |
| 339 |
tempFace.faceIndex = this->FacesNeighborCell->value[i][j]; |
487 |
inflateEnd(&z_); |
| 340 |
tempFace.neighborFace = true; |
|
|
| 341 |
this->FacesOfCell->value[i].push_back(tempFace); |
| 342 |
} |
488 |
} |
| 343 |
} |
|
|
| 344 |
|
| 345 |
//clean up memory |
| 346 |
this->FacesOwnerCell->value.clear(); |
| 347 |
this->FacesNeighborCell->value.clear(); |
| 348 |
return; |
| 349 |
} |
| 350 |
|
489 |
|
| 351 |
// **************************************************************************** |
490 |
delete [] inbuf_; |
| 352 |
// Method: vtkOpenFOAMReader::MakeInternalMesh |
491 |
delete [] outbuf_; |
| 353 |
// |
492 |
inbuf_ = outbuf_ = NULL; |
| 354 |
// Purpose: |
|
|
| 355 |
// derive cell types and create the internal mesh |
| 356 |
// |
| 357 |
// **************************************************************************** |
| 358 |
vtkUnstructuredGrid * vtkOpenFOAMReader::MakeInternalMesh() |
| 359 |
{ |
| 360 |
vtkDebugMacro(<<"Make internal mesh"); |
| 361 |
//initialize variables |
| 362 |
bool foundDup = false; |
| 363 |
vtkstd::vector< int > cellPoints; |
| 364 |
vtkstd::vector< int > tempFaces[2]; |
| 365 |
vtkstd::vector< int > firstFace; |
| 366 |
int pivotPoint = 0; |
| 367 |
int i, j, k, l, pCount; |
| 368 |
int faceCount = 0; |
| 369 |
|
493 |
|
| 370 |
//Create Mesh |
494 |
if(file_ != NULL) |
| 371 |
vtkUnstructuredGrid * internalMesh = vtkUnstructuredGrid::New(); |
495 |
{ |
| 372 |
//loop through each cell, derive type and insert it into the mesh |
496 |
fclose(file_); |
| 373 |
//hexahedron, prism, pyramid, tetrahedron, wedge&tetWedge |
497 |
file_ = NULL; |
| 374 |
for(i = 0; i < (int)this->FacesOfCell->value.size(); i++) //each cell |
498 |
} |
| 375 |
{ |
499 |
// don't reset the line number so that the last line number is |
|
|
500 |
// retained after close |
| 501 |
// lineNumber_ = 0; |
| 502 |
} |
| 376 |
|
503 |
|
| 377 |
//calculate the total points for the cell |
504 |
const vtkStdString extractPath(const vtkStdString& path) const |
| 378 |
//used to derive cell type |
505 |
{ |
| 379 |
int totalPointCount = 0; |
506 |
#if defined(_WIN32) && PARAVIEW_VERSION_MAJOR >= 3 |
| 380 |
for(j = 0; j < (int)this->FacesOfCell->value[i].size(); j++) //each face |
507 |
const vtkStdString pathFindSeparator = "/\\", pathSeparator = "\\"; |
|
|
508 |
#else |
| 509 |
const vtkStdString pathFindSeparator = "/", pathSeparator = "/"; |
| 510 |
#endif |
| 511 |
const size_t pos = path.find_last_of(pathFindSeparator); |
| 512 |
return pos == vtkStdString::npos ? vtkStdString(".") + pathSeparator |
| 513 |
: path.substr(0, pos + 1); |
| 514 |
} |
| 515 |
|
| 516 |
public: |
| 517 |
vtkFoamFile(const vtkStdString& casePath) |
| 518 |
: vtkFoamFileStack(), is13Positions_(false), inputMode_(INPUT_MODE_ERROR), |
| 519 |
stackI_(0), casePath_(casePath) |
| 520 |
{} |
| 521 |
~vtkFoamFile() { close(); } |
| 522 |
|
| 523 |
void setIs13Positions(const bool is13Positions) |
| 524 |
{ is13Positions_ = is13Positions; } |
| 525 |
const bool getIs13Positions() const { return is13Positions_; } |
| 526 |
inputModes getInputMode() const { return inputMode_; } |
| 527 |
const vtkStdString casePath() const { return casePath_; } |
| 528 |
const vtkStdString filePath() const { return extractPath(fileName_); } |
| 529 |
|
| 530 |
vtkStdString expandPath(const vtkStdString& pathIn, |
| 531 |
const vtkStdString& defaultPath) |
| 532 |
{ |
| 533 |
vtkStdString expandedPath; |
| 534 |
bool isExpanded = false, wasPathSeparator = true; |
| 535 |
const int nChars = pathIn.length(); |
| 536 |
for(int charI = 0; charI < nChars;) |
| 537 |
{ |
| 538 |
char c = pathIn[charI]; |
| 539 |
switch(c) |
| 540 |
{ |
| 541 |
case '$': // $-variable expansion |
| 542 |
{ |
| 543 |
vtkStdString variable; |
| 544 |
while(++charI < nChars && (isalnum(pathIn[charI]) |
| 545 |
|| pathIn[charI] == '_')) |
| 546 |
{ |
| 547 |
variable += pathIn[charI]; |
| 548 |
} |
| 549 |
if(variable == "FOAM_CASE") // discard path until the variable |
| 550 |
{ |
| 551 |
expandedPath = casePath_; |
| 552 |
wasPathSeparator = true; |
| 553 |
isExpanded = true; |
| 554 |
} |
| 555 |
else |
| 556 |
{ |
| 557 |
const char *value = getenv(variable.c_str()); |
| 558 |
if(value != NULL) |
| 559 |
{ |
| 560 |
expandedPath += value; |
| 561 |
} |
| 562 |
const size_t len = expandedPath.length(); |
| 563 |
if(len > 0) |
| 564 |
{ |
| 565 |
const char c = expandedPath[len - 1]; |
| 566 |
wasPathSeparator = (c == '/' || c == '\\'); |
| 567 |
} |
| 568 |
else |
| 569 |
{ |
| 570 |
wasPathSeparator = false; |
| 571 |
} |
| 572 |
} |
| 573 |
} |
| 574 |
break; |
| 575 |
case '~': // home directory expansion |
| 576 |
// not using kwsys::SystemTools::ConvertToUnixSlashes() for |
| 577 |
// a bit better handling of "~" |
| 578 |
if(wasPathSeparator) |
| 579 |
{ |
| 580 |
vtkStdString userName; |
| 581 |
while(++charI < nChars && (pathIn[charI] != '/' |
| 582 |
&& pathIn[charI] != '\\') && pathIn[charI] != '$') |
| 583 |
{ |
| 584 |
userName += pathIn[charI]; |
| 585 |
} |
| 586 |
if(userName == "") |
| 587 |
{ |
| 588 |
const char *homePtr = getenv("HOME"); |
| 589 |
if(homePtr == NULL) |
| 590 |
{ |
| 591 |
#if defined(_WIN32) && !defined(__CYGWIN__) || defined(__LIBCATAMOUNT__) |
| 592 |
expandedPath = ""; |
| 593 |
#else |
| 594 |
const struct passwd *pwentry = getpwuid(getuid()); |
| 595 |
if(pwentry == NULL) |
| 596 |
{ |
| 597 |
throw stackString() << "Home directory path not found"; |
| 598 |
} |
| 599 |
expandedPath = pwentry->pw_dir; |
| 600 |
#endif |
| 601 |
} |
| 602 |
else |
| 603 |
{ |
| 604 |
expandedPath = homePtr; |
| 605 |
} |
| 606 |
} |
| 607 |
else |
| 608 |
{ |
| 609 |
#if defined(_WIN32) && !defined(__CYGWIN__) || defined(__LIBCATAMOUNT__) |
| 610 |
const char *homePtr = getenv("HOME"); |
| 611 |
expandedPath = extractPath(homePtr ? homePtr : "") + userName; |
| 612 |
#else |
| 613 |
if(userName == "OpenFOAM") |
| 614 |
{ |
| 615 |
// so far only "~/.OpenFOAM" expansion is supported |
| 616 |
const char *homePtr = getenv("HOME"); |
| 617 |
if(homePtr == NULL) |
| 618 |
{ |
| 619 |
expandedPath = ""; |
| 620 |
} |
| 621 |
else |
| 622 |
{ |
| 623 |
expandedPath = vtkStdString(homePtr) + "/.OpenFOAM"; |
| 624 |
} |
| 625 |
} |
| 626 |
else |
| 627 |
{ |
| 628 |
const struct passwd *pwentry = getpwnam(userName.c_str()); |
| 629 |
if(pwentry == NULL) |
| 630 |
{ |
| 631 |
throw stackString() << "Home directory for user " |
| 632 |
<< userName.c_str() << " not found"; |
| 633 |
} |
| 634 |
expandedPath = pwentry->pw_dir; |
| 635 |
} |
| 636 |
#endif |
| 637 |
} |
| 638 |
wasPathSeparator = false; |
| 639 |
isExpanded = true; |
| 640 |
break; |
| 641 |
} |
| 642 |
// fall through |
| 643 |
default: |
| 644 |
wasPathSeparator = (c == '/' || c == '\\'); |
| 645 |
expandedPath += c; |
| 646 |
charI++; |
| 647 |
} |
| 648 |
} |
| 649 |
if(isExpanded || expandedPath.substr(0, 1) == "/" |
| 650 |
|| expandedPath.substr(0, 1) == "\\") |
| 651 |
{ |
| 652 |
return expandedPath; |
| 653 |
} |
| 654 |
else |
| 381 |
{ |
655 |
{ |
| 382 |
totalPointCount += |
656 |
return defaultPath + expandedPath; |
| 383 |
(int)this->FacePoints-> |
|
|
| 384 |
value[this->FacesOfCell->value[i][j].faceIndex].size(); |
| 385 |
} |
657 |
} |
|
|
658 |
} |
| 386 |
|
659 |
|
| 387 |
// using cell type - order points, create cell, & add to mesh |
660 |
void includeFile(const vtkStdString& includedFileName, |
| 388 |
//OFhex | vtkHexahedron |
661 |
const vtkStdString& defaultPath) |
| 389 |
if (totalPointCount == 24) |
662 |
{ |
|
|
663 |
if(stackI_ >= VTK_FOAMFILE_INCLUDE_STACK_SIZE) |
| 664 |
{ |
| 665 |
throw stackString() << "Exceeded maximum #include recursions of " |
| 666 |
<< VTK_FOAMFILE_INCLUDE_STACK_SIZE; |
| 667 |
} |
| 668 |
// use the default bitwise copy constructor |
| 669 |
stack_[stackI_++] = new vtkFoamFileStack(*this); |
| 670 |
vtkFoamFileStack::reset(); |
| 671 |
|
| 672 |
open(expandPath(includedFileName, defaultPath)); |
| 673 |
} |
| 674 |
|
| 675 |
// the tokenizer |
| 676 |
// returns true if success, false if encountered EOF |
| 677 |
bool read(vtkFoamToken& token) |
| 678 |
{ |
| 679 |
// expanded the outermost loop in nextTokenHead() for performance |
| 680 |
int c; |
| 681 |
while(isspace(c = getc())) // isspace() accepts -1 as EOF |
| 682 |
{ |
| 683 |
if(c == '\n') |
| 684 |
{ |
| 685 |
++lineNumber_; |
| 686 |
#if VTK_FOAMFILE_RECOGNIZE_LINEHEAD |
| 687 |
wasNewline_ = true; |
| 688 |
#endif |
| 689 |
} |
| 690 |
} |
| 691 |
if(c == 47) // '/' == 47 |
| 692 |
{ |
| 693 |
putBack(c); |
| 694 |
c = nextTokenHead(); |
| 695 |
} |
| 696 |
#if VTK_FOAMFILE_RECOGNIZE_LINEHEAD |
| 697 |
if(c != '#') |
| 390 |
{ |
698 |
{ |
| 391 |
faceCount = 0; |
699 |
wasNewline_ = false; |
|
|
700 |
} |
| 701 |
#endif |
| 392 |
|
702 |
|
| 393 |
//get first face |
703 |
const int MAXLEN = 1024; |
| 394 |
for(j = 0; j < |
704 |
char buf[MAXLEN + 1]; |
| 395 |
(int)this->FacePoints-> |
705 |
int charI = 0; |
| 396 |
value[this->FacesOfCell->value[i][0].faceIndex].size(); j++) |
706 |
switch(c) |
| 397 |
{ |
707 |
{ |
| 398 |
firstFace.push_back(this->FacePoints->value[ |
708 |
case '(': case ')': |
| 399 |
this->FacesOfCell->value[i][0].faceIndex][j]); |
709 |
// high-priority punctuation token |
|
|
710 |
token = (char)c; |
| 711 |
return true; |
| 712 |
case '1': case '2': case '3': case '4': case '5': case '6': case '7': |
| 713 |
case '8': case '9': case '0': case '-': |
| 714 |
// undetermined number token |
| 715 |
do |
| 716 |
{ |
| 717 |
buf[charI++] = c; |
| 718 |
} while(isdigit(c = getc()) && charI < MAXLEN); |
| 719 |
if(c != '.' && c != 'e' && c != 'E' && charI < MAXLEN && c != EOF) |
| 720 |
{ |
| 721 |
// label token |
| 722 |
buf[charI] = '\0'; |
| 723 |
token = static_cast<int>(strtol(buf, NULL, 10)); |
| 724 |
putBack(c); |
| 725 |
return true; |
| 726 |
} |
| 727 |
// fall through |
| 728 |
case '.': |
| 729 |
// scalar token |
| 730 |
if(c == '.' && charI < MAXLEN) |
| 731 |
{ |
| 732 |
// read decimal fraction part |
| 733 |
buf[charI++] = c; |
| 734 |
while(isdigit(c = getc()) && charI < MAXLEN) |
| 735 |
{ |
| 736 |
buf[charI++] = c; |
| 737 |
} |
| 738 |
} |
| 739 |
if((c == 'e' || c == 'E') && charI < MAXLEN) |
| 740 |
{ |
| 741 |
// read exponent part |
| 742 |
buf[charI++] = c; |
| 743 |
if(((c = getc()) == '+' || c == '-') && charI < MAXLEN) |
| 744 |
{ |
| 745 |
buf[charI++] = c; |
| 746 |
c = getc(); |
| 747 |
} |
| 748 |
while(isdigit(c) && charI < MAXLEN) |
| 749 |
{ |
| 750 |
buf[charI++] = c; |
| 751 |
c = getc(); |
| 752 |
} |
| 753 |
} |
| 754 |
if(charI == 1 && buf[0] == '-') |
| 755 |
{ |
| 756 |
token = '-'; |
| 757 |
putBack(c); |
| 758 |
return true; |
| 759 |
} |
| 760 |
buf[charI] = '\0'; |
| 761 |
token = strtod(buf, NULL); |
| 762 |
putBack(c); |
| 763 |
break; |
| 764 |
case ';': case '{': case '}': case '[': case ']': case ':': case ',': |
| 765 |
case '=': case '+': case '*': case '/': |
| 766 |
// low-priority punctuation token |
| 767 |
token = (char)c; |
| 768 |
return true; |
| 769 |
case '"': |
| 770 |
{ |
| 771 |
// string token |
| 772 |
bool wasEscape = false; |
| 773 |
while((c = getc()) != EOF && charI < MAXLEN) |
| 774 |
{ |
| 775 |
if(c == '\\' && !wasEscape) |
| 776 |
{ |
| 777 |
wasEscape = true; |
| 778 |
continue; |
| 779 |
} |
| 780 |
else if(c == '"' && !wasEscape) |
| 781 |
{ |
| 782 |
break; |
| 783 |
} |
| 784 |
else if(c == '\n') |
| 785 |
{ |
| 786 |
++lineNumber_; |
| 787 |
if(!wasEscape) |
| 788 |
{ |
| 789 |
throw stackString() << "Unescaped newline in string constant"; |
| 790 |
} |
| 791 |
} |
| 792 |
buf[charI++] = c; |
| 793 |
wasEscape = false; |
| 794 |
} |
| 795 |
buf[charI] = '\0'; |
| 796 |
token = buf; |
| 797 |
} |
| 798 |
break; |
| 799 |
case EOF: |
| 800 |
// end of file |
| 801 |
token.setBad(); |
| 802 |
return false; |
| 803 |
case '$': |
| 804 |
{ |
| 805 |
vtkFoamToken identifierToken; |
| 806 |
if(!read(identifierToken)) |
| 807 |
{ |
| 808 |
throw stackString() << "Unexpected EOF reading identifier"; |
| 809 |
} |
| 810 |
if(identifierToken.type() != vtkFoamToken::STRING) |
| 811 |
{ |
| 812 |
throw stackString() << "Expected a word, found " << identifierToken; |
| 813 |
} |
| 814 |
token.setIdentifier(identifierToken.toString()); |
| 815 |
return true; |
| 816 |
} |
| 817 |
case '#': |
| 818 |
{ |
| 819 |
#if VTK_FOAMFILE_RECOGNIZE_LINEHEAD |
| 820 |
// placing #-directives in the middle of a line looks like |
| 821 |
// valid for the genuine OF 1.5 parser |
| 822 |
if(!wasNewline_) |
| 823 |
{ |
| 824 |
throw stackString() |
| 825 |
<< "Encountered #-directive in the middle of a line"; |
| 826 |
} |
| 827 |
wasNewline_ = false; |
| 828 |
#endif |
| 829 |
// read directive |
| 830 |
vtkFoamToken directiveToken; |
| 831 |
if(!read(directiveToken)) |
| 832 |
{ |
| 833 |
throw stackString() << "Unexpected EOF reading directive"; |
| 834 |
} |
| 835 |
if(directiveToken == "include") |
| 836 |
{ |
| 837 |
vtkFoamToken fileNameToken; |
| 838 |
if(!read(fileNameToken)) |
| 839 |
{ |
| 840 |
throw stackString() << "Unexpected EOF reading filename"; |
| 841 |
} |
| 842 |
includeFile(fileNameToken.toString(), extractPath(fileName_)); |
| 843 |
} |
| 844 |
else if(directiveToken == "inputMode") |
| 845 |
{ |
| 846 |
vtkFoamToken modeToken; |
| 847 |
if(!read(modeToken)) |
| 848 |
{ |
| 849 |
throw stackString() << "Unexpected EOF reading inputMode specifier"; |
| 850 |
} |
| 851 |
if(modeToken == "merge") |
| 852 |
{ |
| 853 |
inputMode_ = INPUT_MODE_MERGE; |
| 854 |
} |
| 855 |
else if(modeToken == "overwrite") |
| 856 |
{ |
| 857 |
inputMode_ = INPUT_MODE_OVERWRITE; |
| 858 |
} |
| 859 |
else if(modeToken == "error" || modeToken == "default") |
| 860 |
{ |
| 861 |
inputMode_ = INPUT_MODE_ERROR; |
| 862 |
} |
| 863 |
else |
| 864 |
{ |
| 865 |
throw stackString() << "Expected one of inputMode specifiers " |
| 866 |
"(merge, overwrite, error, default), found " << modeToken; |
| 867 |
} |
| 868 |
} |
| 869 |
else |
| 870 |
{ |
| 871 |
throw stackString() << "Unsupported directive " << directiveToken; |
| 872 |
} |
| 873 |
return read(token); |
| 874 |
} |
| 875 |
default: |
| 876 |
// parses as a word token, but gives the STRING type for simplicity |
| 877 |
int inBrace = 0; |
| 878 |
do |
| 879 |
{ |
| 880 |
if(c == '(') |
| 881 |
{ |
| 882 |
inBrace++; |
| 883 |
} |
| 884 |
else if(c == ')' && --inBrace == -1) |
| 885 |
{ |
| 886 |
break; |
| 887 |
} |
| 888 |
buf[charI++] = c; |
| 889 |
// valid characters that constitutes a word |
| 890 |
// cf. src/OpenFOAM/primitives/strings/word/wordI.H |
| 891 |
} while((c = getc()) != EOF && !isspace(c) && c != '"' && c != '/' |
| 892 |
&& c != ';' && c != '{' && c != '}' && charI < MAXLEN); |
| 893 |
buf[charI] = '\0'; |
| 894 |
token = buf; |
| 895 |
putBack(c); |
| 896 |
} |
| 897 |
|
| 898 |
if(c == EOF) |
| 899 |
{ |
| 900 |
throwUnexpectedEOFException(); |
| 901 |
} |
| 902 |
if(charI == MAXLEN) |
| 903 |
{ |
| 904 |
throw stackString() << "Exceeded maximum allowed length of " << MAXLEN |
| 905 |
<< " chars"; |
| 906 |
} |
| 907 |
return true; |
| 908 |
} |
| 909 |
|
| 910 |
void open(const vtkStdString& fileName) |
| 911 |
{ |
| 912 |
// reset line number to indicate the beginning of the file when an |
| 913 |
// exception is thrown |
| 914 |
lineNumber_ = 0; |
| 915 |
fileName_ = fileName; |
| 916 |
|
| 917 |
if(file_ != NULL) |
| 918 |
{ |
| 919 |
throw stackString() << "File already opened within this object"; |
| 920 |
} |
| 921 |
|
| 922 |
if((file_ = fopen(fileName.c_str(), "rb")) == NULL) |
| 923 |
{ |
| 924 |
throw stackString() << "Can't open"; |
| 925 |
} |
| 926 |
|
| 927 |
unsigned char zMagic[2]; |
| 928 |
if(fread(zMagic, 1, 2, file_) == 2 |
| 929 |
&& zMagic[0] == 0x1f && zMagic[1] == 0x8b) |
| 930 |
{ |
| 931 |
// gzip-compressed format |
| 932 |
z_.avail_in = 0; |
| 933 |
z_.next_in = Z_NULL; |
| 934 |
// + 32 to automatically recognize gzip format |
| 935 |
if(inflateInit2(&z_, 15 + 32) == Z_OK) |
| 936 |
{ |
| 937 |
isCompressed_ = true; |
| 938 |
inbuf_ = new unsigned char[VTK_FOAMFILE_INBUFSIZE]; |
| 939 |
} |
| 940 |
else |
| 941 |
{ |
| 942 |
fclose(file_); |
| 943 |
file_ = NULL; |
| 944 |
throw stackString() << "Can't init zstream " << (z_.msg ? z_.msg : ""); |
| 945 |
} |
| 946 |
} |
| 947 |
else |
| 948 |
{ |
| 949 |
// uncompressed format |
| 950 |
isCompressed_ = false; |
| 951 |
} |
| 952 |
rewind(file_); |
| 953 |
|
| 954 |
zStatus_ = Z_OK; |
| 955 |
outbuf_ = new unsigned char[VTK_FOAMFILE_OUTBUFSIZE + 1]; |
| 956 |
bufPtr_ = outbuf_ + 1; |
| 957 |
bufEndPtr_ = bufPtr_; |
| 958 |
lineNumber_ = 1; |
| 959 |
} |
| 960 |
|
| 961 |
void close() |
| 962 |
{ |
| 963 |
while(closeIncludedFile()); |
| 964 |
clear(); |
| 965 |
} |
| 966 |
|
| 967 |
// gzread with buffering handling |
| 968 |
int read(unsigned char *buf, const int len) |
| 969 |
{ |
| 970 |
int readlen; |
| 971 |
const int buflen = bufEndPtr_ - bufPtr_; |
| 972 |
if(len > buflen) |
| 973 |
{ |
| 974 |
memcpy(buf, bufPtr_, buflen); |
| 975 |
readlen = inflateNext(buf + buflen, len - buflen); |
| 976 |
if(readlen >= 0) |
| 977 |
{ |
| 978 |
readlen += buflen; |
| 979 |
} |
| 980 |
else |
| 981 |
{ |
| 982 |
if(buflen == 0) // return EOF |
| 983 |
{ |
| 984 |
readlen = -1; |
| 985 |
} |
| 986 |
else |
| 987 |
{ |
| 988 |
readlen = buflen; |
| 989 |
} |
| 990 |
} |
| 991 |
bufPtr_ = bufEndPtr_; |
| 992 |
} |
| 993 |
else |
| 994 |
{ |
| 995 |
memcpy(buf, bufPtr_, len); |
| 996 |
bufPtr_ += len; |
| 997 |
readlen = len; |
| 998 |
} |
| 999 |
for(int i = 0; i < readlen; i++) |
| 1000 |
{ |
| 1001 |
if(buf[i] == '\n') |
| 1002 |
{ |
| 1003 |
lineNumber_++; |
| 1004 |
} |
| 1005 |
} |
| 1006 |
return readlen; |
| 1007 |
} |
| 1008 |
|
| 1009 |
void readExpecting(const char expected) |
| 1010 |
{ |
| 1011 |
// skip prepending invalid chars |
| 1012 |
// expanded the outermost loop in nextTokenHead() for performance |
| 1013 |
int c; |
| 1014 |
while(isspace(c = getc())) // isspace() accepts -1 as EOF |
| 1015 |
{ |
| 1016 |
if(c == '\n') |
| 1017 |
{ |
| 1018 |
++lineNumber_; |
| 1019 |
#if VTK_FOAMFILE_RECOGNIZE_LINEHEAD |
| 1020 |
wasNewline_ = true; |
| 1021 |
#endif |
| 1022 |
} |
| 1023 |
} |
| 1024 |
if(c == 47) // '/' == 47 |
| 1025 |
{ |
| 1026 |
putBack(c); |
| 1027 |
c = nextTokenHead(); |
| 1028 |
} |
| 1029 |
if(c != expected) |
| 1030 |
{ |
| 1031 |
throwUnexpectedTokenException(expected, c); |
| 1032 |
} |
| 1033 |
} |
| 1034 |
|
| 1035 |
void readExpecting(const char* str) |
| 1036 |
{ |
| 1037 |
vtkFoamToken t; |
| 1038 |
if(!read(t) || t != str) |
| 1039 |
{ |
| 1040 |
throw stackString() << "Expected string \"" << str << "\", found " << t; |
| 1041 |
} |
| 1042 |
} |
| 1043 |
|
| 1044 |
template<class T> T readValue(); //{ return static_cast<T>(0); } |
| 1045 |
}; |
| 1046 |
|
| 1047 |
int vtkOpenFOAMReader::vtkFoamFile::readNext() |
| 1048 |
{ |
| 1049 |
if(!inflateNext(outbuf_ + 1, VTK_FOAMFILE_OUTBUFSIZE)) |
| 1050 |
{ |
| 1051 |
return closeIncludedFile() ? getc() : EOF; |
| 1052 |
} |
| 1053 |
return *bufPtr_++; |
| 1054 |
} |
| 1055 |
|
| 1056 |
// specialized for reading an integer value. |
| 1057 |
// not using the standard strtol() for speed reason. |
| 1058 |
template<> int vtkOpenFOAMReader::vtkFoamFile::readValue() |
| 1059 |
{ |
| 1060 |
// skip prepending invalid chars |
| 1061 |
// expanded the outermost loop in nextTokenHead() for performance |
| 1062 |
int c; |
| 1063 |
while(isspace(c = getc())) // isspace() accepts -1 as EOF |
| 1064 |
{ |
| 1065 |
if(c == '\n') |
| 1066 |
{ |
| 1067 |
++lineNumber_; |
| 1068 |
#if VTK_FOAMFILE_RECOGNIZE_LINEHEAD |
| 1069 |
wasNewline_ = true; |
| 1070 |
#endif |
| 1071 |
} |
| 1072 |
} |
| 1073 |
if(c == 47) // '/' == 47 |
| 1074 |
{ |
| 1075 |
putBack(c); |
| 1076 |
c = nextTokenHead(); |
| 1077 |
} |
| 1078 |
|
| 1079 |
int nonNegative = c - 45; // '-' == 45 |
| 1080 |
if(nonNegative == 0 || c == 43) // '+' == 43 |
| 1081 |
{ |
| 1082 |
c = getc(); |
| 1083 |
if(c == '\n') |
| 1084 |
{ |
| 1085 |
++lineNumber_; |
| 1086 |
#if VTK_FOAMFILE_RECOGNIZE_LINEHEAD |
| 1087 |
wasNewline_ = true; |
| 1088 |
#endif |
| 1089 |
} |
| 1090 |
} |
| 1091 |
|
| 1092 |
if(!isdigit(c)) // isdigit() accepts -1 as EOF |
| 1093 |
{ |
| 1094 |
if(c == EOF) |
| 1095 |
{ |
| 1096 |
throwUnexpectedEOFException(); |
| 1097 |
} |
| 1098 |
else |
| 1099 |
{ |
| 1100 |
throwUnexpectedNondigitCharExecption(c); |
| 1101 |
} |
| 1102 |
} |
| 1103 |
|
| 1104 |
int num = c - 48; // '0' == 48 |
| 1105 |
while(isdigit(c = getc())) |
| 1106 |
{ |
| 1107 |
num = 10 * num + c - 48; |
| 1108 |
} |
| 1109 |
|
| 1110 |
if(c == EOF) |
| 1111 |
{ |
| 1112 |
throwUnexpectedEOFException(); |
| 1113 |
} |
| 1114 |
putBack(c); |
| 1115 |
|
| 1116 |
return nonNegative ? num : -num; |
| 1117 |
} |
| 1118 |
|
| 1119 |
// extreamely simplified high-performing string to floating point |
| 1120 |
// conversion code based on |
| 1121 |
// ParaView3/VTK/Utilities/vtksqlite/vtk_sqlite3.c |
| 1122 |
template<> float vtkOpenFOAMReader::vtkFoamFile::readValue() |
| 1123 |
{ |
| 1124 |
// skip prepending invalid chars |
| 1125 |
// expanded the outermost loop in nextTokenHead() for performance |
| 1126 |
int c; |
| 1127 |
while(isspace(c = getc())) // isspace() accepts -1 as EOF |
| 1128 |
{ |
| 1129 |
if(c == '\n') |
| 1130 |
{ |
| 1131 |
++lineNumber_; |
| 1132 |
#if VTK_FOAMFILE_RECOGNIZE_LINEHEAD |
| 1133 |
wasNewline_ = true; |
| 1134 |
#endif |
| 1135 |
} |
| 1136 |
} |
| 1137 |
if(c == 47) // '/' == 47 |
| 1138 |
{ |
| 1139 |
putBack(c); |
| 1140 |
c = nextTokenHead(); |
| 1141 |
} |
| 1142 |
|
| 1143 |
// determine sign |
| 1144 |
int nonNegative = c - 45; // '-' == 45 |
| 1145 |
if(nonNegative == 0 || c == 43) // '+' == 43 |
| 1146 |
{ |
| 1147 |
c = getc(); |
| 1148 |
if(c == '\n') |
| 1149 |
{ |
| 1150 |
++lineNumber_; |
| 1151 |
#if VTK_FOAMFILE_RECOGNIZE_LINEHEAD |
| 1152 |
wasNewline_ = true; |
| 1153 |
#endif |
| 1154 |
} |
| 1155 |
} |
| 1156 |
|
| 1157 |
if(!isdigit(c) && c != 46) // '.' == 46, isdigit() accepts EOF |
| 1158 |
{ |
| 1159 |
throwUnexpectedNondigitCharExecption(c); |
| 1160 |
} |
| 1161 |
|
| 1162 |
// read integer part |
| 1163 |
double num = c - 48; // '0' == 48 |
| 1164 |
while(isdigit(c = getc())) |
| 1165 |
{ |
| 1166 |
num = num * 10.0 + (c - 48); |
| 1167 |
} |
| 1168 |
|
| 1169 |
// read decimal part |
| 1170 |
if(c == 46) // '.' |
| 1171 |
{ |
| 1172 |
double divisor = 1.0; |
| 1173 |
|
| 1174 |
while(isdigit(c = getc())) |
| 1175 |
{ |
| 1176 |
num = num * 10.0 + (c - 48); |
| 1177 |
divisor *= 10.0; |
| 1178 |
} |
| 1179 |
num /= divisor; |
| 1180 |
} |
| 1181 |
|
| 1182 |
// read exponent part |
| 1183 |
if(c == 69 || c == 101) // 'E' == 69, 'e' == 101 |
| 1184 |
{ |
| 1185 |
int esign = 1; |
| 1186 |
int eval = 0; |
| 1187 |
double scale = 1.0; |
| 1188 |
|
| 1189 |
c = getc(); |
| 1190 |
if(c == 45) // '-' |
| 1191 |
{ |
| 1192 |
esign = -1; |
| 1193 |
c = getc(); |
| 1194 |
} |
| 1195 |
else if(c == 43) // '+' |
| 1196 |
{ |
| 1197 |
c = getc(); |
| 1198 |
} |
| 1199 |
|
| 1200 |
while(isdigit(c)) |
| 1201 |
{ |
| 1202 |
eval = eval * 10 + (c - 48); |
| 1203 |
c = getc(); |
| 1204 |
} |
| 1205 |
|
| 1206 |
// fast exponent multiplication! |
| 1207 |
while(eval >= 64) |
| 1208 |
{ |
| 1209 |
scale *= 1.0e+64; |
| 1210 |
eval -= 64; |
| 1211 |
} |
| 1212 |
while(eval >= 16) |
| 1213 |
{ |
| 1214 |
scale *= 1.0e+16; |
| 1215 |
eval -= 16; |
| 1216 |
} |
| 1217 |
while(eval >= 4) |
| 1218 |
{ |
| 1219 |
scale *= 1.0e+4; |
| 1220 |
eval -= 4; |
| 1221 |
} |
| 1222 |
while(eval >= 1) |
| 1223 |
{ |
| 1224 |
scale *= 1.0e+1; |
| 1225 |
eval -= 1; |
| 1226 |
} |
| 1227 |
|
| 1228 |
if(esign < 0) |
| 1229 |
{ |
| 1230 |
num /= scale; |
| 1231 |
} |
| 1232 |
else |
| 1233 |
{ |
| 1234 |
num *= scale; |
| 1235 |
} |
| 1236 |
} |
| 1237 |
|
| 1238 |
if(c == EOF) |
| 1239 |
{ |
| 1240 |
throwUnexpectedEOFException(); |
| 1241 |
} |
| 1242 |
putBack(c); |
| 1243 |
|
| 1244 |
return static_cast<float>(nonNegative ? num : -num); |
| 1245 |
} |
| 1246 |
|
| 1247 |
// hacks to keep exception throwing code out-of-line to make |
| 1248 |
// putBack() and readExpecting() inline expandable |
| 1249 |
void vtkOpenFOAMReader::vtkFoamFile::throwUnexpectedEOFException() |
| 1250 |
{ throw stackString() << "Unexpected EOF"; } |
| 1251 |
|
| 1252 |
void vtkOpenFOAMReader::vtkFoamFile::throwUnexpectedNondigitCharExecption( |
| 1253 |
const int c) |
| 1254 |
{ |
| 1255 |
throw stackString() << "Expected a number, found a non-digit character " |
| 1256 |
<< static_cast<char>(c); |
| 1257 |
} |
| 1258 |
|
| 1259 |
void vtkOpenFOAMReader::vtkFoamFile::throwUnexpectedTokenException( |
| 1260 |
const char expected, const int c) |
| 1261 |
{ |
| 1262 |
vtkFoamError sstr; |
| 1263 |
sstr << stackString() << "Expected punctuation token '" << expected |
| 1264 |
<< "', found "; |
| 1265 |
if(c == EOF) |
| 1266 |
{ |
| 1267 |
sstr << "EOF"; |
| 1268 |
} |
| 1269 |
else |
| 1270 |
{ |
| 1271 |
sstr << static_cast<char>(c); |
| 1272 |
} |
| 1273 |
throw sstr; |
| 1274 |
} |
| 1275 |
|
| 1276 |
void vtkOpenFOAMReader::vtkFoamFile::throwDuplicatedPutBackException() |
| 1277 |
{ throw stackString() << "Attempted duplicated putBack()"; } |
| 1278 |
|
| 1279 |
bool vtkOpenFOAMReader::vtkFoamFile::inflateNext(unsigned char *buf, |
| 1280 |
int requestSize) |
| 1281 |
{ |
| 1282 |
int size; |
| 1283 |
if(isCompressed_) |
| 1284 |
{ |
| 1285 |
if(zStatus_ != Z_OK) |
| 1286 |
{ |
| 1287 |
return false; |
| 1288 |
} |
| 1289 |
z_.next_out = buf; |
| 1290 |
z_.avail_out = requestSize; |
| 1291 |
|
| 1292 |
do |
| 1293 |
{ |
| 1294 |
if(z_.avail_in == 0) |
| 1295 |
{ |
| 1296 |
z_.next_in = inbuf_; |
| 1297 |
z_.avail_in = fread(inbuf_, 1, VTK_FOAMFILE_INBUFSIZE, file_); |
| 1298 |
if(ferror(file_)) |
| 1299 |
{ |
| 1300 |
throw stackString() << "Fread failed"; |
| 1301 |
} |
| 1302 |
} |
| 1303 |
zStatus_ = inflate(&z_, Z_NO_FLUSH); |
| 1304 |
if(zStatus_ == Z_STREAM_END |
| 1305 |
#if VTK_FOAMFILE_OMIT_CRCCHECK |
| 1306 |
// the dummy CRC function causes data error when finalizing |
| 1307 |
// so we have to proceed even when a data error is detected |
| 1308 |
|| zStatus_ == Z_DATA_ERROR |
| 1309 |
#endif |
| 1310 |
) |
| 1311 |
{ |
| 1312 |
break; |
| 1313 |
} |
| 1314 |
if(zStatus_ != Z_OK) |
| 1315 |
{ |
| 1316 |
throw stackString() << "Inflation failed: " << (z_.msg ? z_.msg : ""); |
| 1317 |
} |
| 1318 |
} |
| 1319 |
while(z_.avail_out > 0); |
| 1320 |
|
| 1321 |
size = requestSize - z_.avail_out; |
| 1322 |
} |
| 1323 |
else |
| 1324 |
{ |
| 1325 |
// not compressed |
| 1326 |
size = fread(buf, 1, requestSize, file_); |
| 1327 |
} |
| 1328 |
|
| 1329 |
if(size <= 0) |
| 1330 |
{ |
| 1331 |
// retain the current location bufPtr_ to the end of the buffer so that |
| 1332 |
// getc() returns EOF again when called next time |
| 1333 |
return false; |
| 1334 |
} |
| 1335 |
// size > 0 |
| 1336 |
bufPtr_ = outbuf_ + 1; // reserve the first byte for getback char |
| 1337 |
bufEndPtr_ = bufPtr_ + size; |
| 1338 |
return true; |
| 1339 |
} |
| 1340 |
|
| 1341 |
// get next semantically valid character |
| 1342 |
int vtkOpenFOAMReader::vtkFoamFile::nextTokenHead() |
| 1343 |
{ |
| 1344 |
for(;;) |
| 1345 |
{ |
| 1346 |
int c; |
| 1347 |
while(isspace(c = getc())) // isspace() accepts -1 as EOF |
| 1348 |
{ |
| 1349 |
if(c == '\n') |
| 1350 |
{ |
| 1351 |
++lineNumber_; |
| 1352 |
#if VTK_FOAMFILE_RECOGNIZE_LINEHEAD |
| 1353 |
wasNewline_ = true; |
| 1354 |
#endif |
| 1355 |
} |
| 1356 |
} |
| 1357 |
if(c == '/') |
| 1358 |
{ |
| 1359 |
if((c = getc()) == '/') |
| 1360 |
{ |
| 1361 |
while((c = getc()) != EOF && c != '\n'); |
| 1362 |
if(c == EOF) |
| 1363 |
{ |
| 1364 |
return c; |
| 1365 |
} |
| 1366 |
++lineNumber_; |
| 1367 |
#if VTK_FOAMFILE_RECOGNIZE_LINEHEAD |
| 1368 |
wasNewline_ = true; |
| 1369 |
#endif |
| 1370 |
} |
| 1371 |
else if(c == '*') |
| 1372 |
{ |
| 1373 |
for(;;) |
| 1374 |
{ |
| 1375 |
while((c = getc()) != EOF && c != '*') |
| 1376 |
{ |
| 1377 |
if(c == '\n') |
| 1378 |
{ |
| 1379 |
++lineNumber_; |
| 1380 |
} |
| 1381 |
} |
| 1382 |
if(c == EOF) |
| 1383 |
{ |
| 1384 |
return c; |
| 1385 |
} |
| 1386 |
else if((c = getc()) == '/') |
| 1387 |
{ |
| 1388 |
break; |
| 1389 |
} |
| 1390 |
putBack(c); |
| 1391 |
} |
| 1392 |
} |
| 1393 |
else |
| 1394 |
{ |
| 1395 |
putBack(c); // may be an EOF |
| 1396 |
return '/'; |
| 1397 |
} |
| 1398 |
} |
| 1399 |
else // may be an EOF |
| 1400 |
{ |
| 1401 |
return c; |
| 1402 |
} |
| 1403 |
} |
| 1404 |
} |
| 1405 |
|
| 1406 |
//----------------------------------------------------------------------------- |
| 1407 |
// class vtkFoamIOobject |
| 1408 |
// holds file handle, file format, name of the object the file holds and |
| 1409 |
// type of the object. |
| 1410 |
struct vtkOpenFOAMReader::vtkFoamIOobject: public vtkFoamFile |
| 1411 |
{ |
| 1412 |
public: |
| 1413 |
enum fileFormat { UNDEFINED, ASCII, BINARY }; |
| 1414 |
|
| 1415 |
private: |
| 1416 |
fileFormat format_; |
| 1417 |
vtkStdString objectName_; |
| 1418 |
vtkStdString headerClassName_; |
| 1419 |
vtkFoamError e_; |
| 1420 |
|
| 1421 |
vtkFoamIOobject(); |
| 1422 |
void readHeader(); // defined later |
| 1423 |
public: |
| 1424 |
vtkFoamIOobject(const vtkStdString& casePath) |
| 1425 |
: vtkFoamFile(casePath), format_(UNDEFINED), e_() {} |
| 1426 |
~vtkFoamIOobject() { close(); } |
| 1427 |
|
| 1428 |
bool open(const vtkStdString& file) |
| 1429 |
{ |
| 1430 |
try |
| 1431 |
{ |
| 1432 |
vtkFoamFile::open(file); |
| 1433 |
} |
| 1434 |
catch(vtkFoamError& e) |
| 1435 |
{ |
| 1436 |
e_ = e; |
| 1437 |
return false; |
| 1438 |
} |
| 1439 |
|
| 1440 |
try |
| 1441 |
{ |
| 1442 |
readHeader(); |
| 1443 |
} |
| 1444 |
catch(vtkFoamError& e) |
| 1445 |
{ |
| 1446 |
vtkFoamFile::close(); |
| 1447 |
e_ = e; |
| 1448 |
return false; |
| 1449 |
} |
| 1450 |
return true; |
| 1451 |
} |
| 1452 |
|
| 1453 |
void close() |
| 1454 |
{ |
| 1455 |
vtkFoamFile::close(); |
| 1456 |
format_ = UNDEFINED; |
| 1457 |
objectName_.erase(); |
| 1458 |
headerClassName_.erase(); |
| 1459 |
e_.erase(); |
| 1460 |
} |
| 1461 |
const fileFormat format() const { return format_; } |
| 1462 |
const vtkStdString& className() const { return headerClassName_; } |
| 1463 |
const vtkStdString& objectName() const { return objectName_; } |
| 1464 |
const vtkFoamError& error() const { return e_; } |
| 1465 |
void setError(const vtkFoamError& e) { e_ = e; } |
| 1466 |
}; |
| 1467 |
|
| 1468 |
//----------------------------------------------------------------------------- |
| 1469 |
// class vtkFoamEntryValue |
| 1470 |
// a class that represents a value of a dictionary entry that corresponds to |
| 1471 |
// its keyword. note that an entry can have more than one value. |
| 1472 |
struct vtkOpenFOAMReader::vtkFoamEntryValue: public vtkFoamToken |
| 1473 |
{ |
| 1474 |
private: |
| 1475 |
bool isUniform_; |
| 1476 |
bool managed_; |
| 1477 |
vtkFoamEntry *upperEntryPtr_; |
| 1478 |
|
| 1479 |
vtkFoamEntryValue(); |
| 1480 |
vtkObjectBase *toVTKObject() { return vtkObjectPtr_; } |
| 1481 |
void clear(); |
| 1482 |
void readList(vtkFoamIOobject& io); |
| 1483 |
|
| 1484 |
protected: |
| 1485 |
// reads primitive int/float lists |
| 1486 |
template <typename listT, typename primitiveT> class listTraits |
| 1487 |
{ |
| 1488 |
listT *ptr_; |
| 1489 |
|
| 1490 |
public: |
| 1491 |
listTraits(): ptr_(listT::New()) {} |
| 1492 |
listT *ptr() { return ptr_; } |
| 1493 |
void readUniformValues(vtkFoamIOobject& io, const int size) |
| 1494 |
{ |
| 1495 |
primitiveT value = io.readValue<primitiveT>(); |
| 1496 |
for(int i = 0; i < size; i++) |
| 1497 |
{ |
| 1498 |
ptr_->SetValue(i, value); |
| 1499 |
} |
| 1500 |
} |
| 1501 |
void readAsciiList(vtkFoamIOobject& io, const int size) |
| 1502 |
{ |
| 1503 |
for(int i = 0; i < size; i++) |
| 1504 |
{ |
| 1505 |
ptr_->SetValue(i, io.readValue<primitiveT>()); |
| 1506 |
} |
| 1507 |
} |
| 1508 |
void readBinaryList(vtkFoamIOobject& io, const int size) |
| 1509 |
{ |
| 1510 |
io.read(reinterpret_cast<unsigned char *>(ptr_->GetPointer(0)), |
| 1511 |
size * sizeof(primitiveT)); |
| 1512 |
} |
| 1513 |
void readValue(vtkFoamIOobject&, vtkFoamToken& currToken) |
| 1514 |
{ |
| 1515 |
if(!currToken.is<primitiveT>()) |
| 1516 |
{ |
| 1517 |
throw vtkFoamError() << "Expected an integer or a (, found " |
| 1518 |
<< currToken; |
| 1519 |
} |
| 1520 |
ptr_->InsertNextValue(currToken.to<primitiveT>()); |
| 1521 |
} |
| 1522 |
}; |
| 1523 |
|
| 1524 |
// reads rank 1 lists of types vector, sphericalTensor, symmTensor |
| 1525 |
// and tensor. if isPositions is true it reads Cloud type of data as |
| 1526 |
// particle positions. cf. (the positions format) |
| 1527 |
// src/lagrangian/basic/particle/particleIO.C |
| 1528 |
template <typename listT, typename primitiveT, |
| 1529 |
int nComponents, bool isPositions> class vectorListTraits |
| 1530 |
{ |
| 1531 |
listT *ptr_; |
| 1532 |
|
| 1533 |
public: |
| 1534 |
vectorListTraits(): ptr_(listT::New()) |
| 1535 |
{ ptr_->SetNumberOfComponents(nComponents); } |
| 1536 |
listT *ptr() { return ptr_; } |
| 1537 |
void readUniformValues(vtkFoamIOobject& io, const int size) |
| 1538 |
{ |
| 1539 |
io.readExpecting('('); |
| 1540 |
primitiveT vectorValue[nComponents]; |
| 1541 |
for(int j = 0; j < nComponents; j++) |
| 1542 |
{ |
| 1543 |
vectorValue[j] = io.readValue<primitiveT>(); |
| 1544 |
} |
| 1545 |
for(int i = 0; i < size; i++) |
| 1546 |
{ |
| 1547 |
ptr_->SetTuple(i, vectorValue); |
| 1548 |
} |
| 1549 |
io.readExpecting(')'); |
| 1550 |
if(isPositions) |
| 1551 |
{ |
| 1552 |
// skip label celli |
| 1553 |
io.readValue<int>(); |
| 1554 |
} |
| 1555 |
} |
| 1556 |
void readAsciiList(vtkFoamIOobject& io, const int size) |
| 1557 |
{ |
| 1558 |
for(int i = 0; i < size; i++) |
| 1559 |
{ |
| 1560 |
io.readExpecting('('); |
| 1561 |
primitiveT *vectorTupleI = ptr_->GetPointer(nComponents * i); |
| 1562 |
for(int j = 0; j < nComponents; j++) |
| 1563 |
{ |
| 1564 |
vectorTupleI[j] = io.readValue<primitiveT>(); |
| 1565 |
} |
| 1566 |
io.readExpecting(')'); |
| 1567 |
if(isPositions) |
| 1568 |
{ |
| 1569 |
// skip label celli |
| 1570 |
io.readValue<int>(); |
| 1571 |
} |
| 1572 |
} |
| 1573 |
} |
| 1574 |
void readBinaryList(vtkFoamIOobject& io, const int size) |
| 1575 |
{ |
| 1576 |
if(isPositions) // lagrangian/positions (class Cloud) |
| 1577 |
{ |
| 1578 |
// allocate space along with the larger 1.4 format since the |
| 1579 |
// size must be determined at compile-time. we allocate on the |
| 1580 |
// stack to avoid leak when an exception is thrown. |
| 1581 |
unsigned char buffer[sizeof(double) * (nComponents + 1) |
| 1582 |
+ 2 * sizeof(int)]; |
| 1583 |
const int nBytes = (io.getIs13Positions() |
| 1584 |
// skip label celli |
| 1585 |
? sizeof(double) * nComponents + sizeof(int) |
| 1586 |
// skip label celli, label facei and scalar stepFraction |
| 1587 |
: sizeof(double) * (nComponents + 1) + 2 * sizeof(int)); |
| 1588 |
for(int i = 0; i < size; i++) |
| 1589 |
{ |
| 1590 |
io.readExpecting('('); |
| 1591 |
io.read(buffer, nBytes); |
| 1592 |
ptr_->SetTuple(i, reinterpret_cast<double *>(buffer)); |
| 1593 |
io.readExpecting(')'); |
| 1594 |
} |
| 1595 |
} |
| 1596 |
else |
| 1597 |
{ |
| 1598 |
for(int i = 0; i < size; i++) |
| 1599 |
{ |
| 1600 |
double buffer[nComponents]; |
| 1601 |
io.read(reinterpret_cast<unsigned char *>(buffer), |
| 1602 |
sizeof(double) * nComponents); |
| 1603 |
ptr_->SetTuple(i, buffer); |
| 1604 |
} |
| 1605 |
} |
| 1606 |
} |
| 1607 |
void readValue(vtkFoamIOobject& io, vtkFoamToken& currToken) |
| 1608 |
{ |
| 1609 |
if(currToken != '(') |
| 1610 |
{ |
| 1611 |
throw vtkFoamError() << "Expected '(', found " << currToken; |
| 1612 |
} |
| 1613 |
primitiveT v[nComponents]; |
| 1614 |
for(int j = 0; j < nComponents; j++) |
| 1615 |
{ |
| 1616 |
v[j] = io.readValue<primitiveT>(); |
| 1617 |
} |
| 1618 |
ptr_->InsertNextTuple(v); |
| 1619 |
io.readExpecting(')'); |
| 1620 |
} |
| 1621 |
}; |
| 1622 |
|
| 1623 |
public: |
| 1624 |
vtkFoamEntryValue(vtkFoamEntry *upperEntryPtr) |
| 1625 |
: vtkFoamToken(), isUniform_(false), managed_(true), |
| 1626 |
upperEntryPtr_(upperEntryPtr) {} |
| 1627 |
vtkFoamEntryValue(vtkFoamEntryValue&, vtkFoamEntry *); |
| 1628 |
~vtkFoamEntryValue() { clear(); } |
| 1629 |
|
| 1630 |
void setEmptyList() { clear(); isUniform_ = false; type_ = EMPTYLIST; } |
| 1631 |
bool isUniform() const { return isUniform_; } |
| 1632 |
void read(vtkFoamIOobject& io); |
| 1633 |
void readDictionary(vtkFoamIOobject& io, const vtkFoamToken& firstKeyword); |
| 1634 |
vtkIntArray& labelList() const { return *labelListPtr_; } |
| 1635 |
const intVectorVector& labelListList() const { return *labelListListPtr_; } |
| 1636 |
vtkFloatArray& scalarList() { return *scalarListPtr_; } |
| 1637 |
vtkFloatArray& vectorList() { return *vectorListPtr_; } |
| 1638 |
vtkFoamDict& dictionary() { return *dictPtr_; } |
| 1639 |
|
| 1640 |
void *ptr() |
| 1641 |
{ |
| 1642 |
managed_ = false; // the returned pointer will not be deleted by the d'tor |
| 1643 |
return (void *)labelListPtr_; // all list pointers are in a single union |
| 1644 |
} |
| 1645 |
|
| 1646 |
vtkStdString toString() const |
| 1647 |
{ return type_ == STRING ? vtkFoamToken::toString() : vtkStdString(); } |
| 1648 |
float toFloat() const |
| 1649 |
{ |
| 1650 |
return type_ == SCALAR || type_ == LABEL ? vtkFoamToken::to<float>() : 0.0F; |
| 1651 |
} |
| 1652 |
double toDouble() const |
| 1653 |
{ |
| 1654 |
return type_ == SCALAR || type_ == LABEL ? vtkFoamToken::to<double>() : 0.0; |
| 1655 |
} |
| 1656 |
int toInt() const |
| 1657 |
{ return type_ == LABEL ? vtkFoamToken::to<int>() : 0; } |
| 1658 |
|
| 1659 |
// the following two are for an exceptional expression of |
| 1660 |
// `LABEL{LABELorSCALAR}' without type prefix (e. g. `2{-0}' in |
| 1661 |
// mixedRhoE B.C. in rhopSonicFoam/shockTube) |
| 1662 |
void makeLabelList(const int labelValue, const int size) |
| 1663 |
{ |
| 1664 |
labelListPtr_ = vtkIntArray::New(); |
| 1665 |
type_ = LABELLIST; |
| 1666 |
vtkIntArray &ll = *labelListPtr_; |
| 1667 |
ll.SetNumberOfValues(size); |
| 1668 |
for(int i = 0; i < size; i++) |
| 1669 |
{ |
| 1670 |
ll.SetValue(i, labelValue); |
| 1671 |
} |
| 1672 |
} |
| 1673 |
void makeScalarList(const float scalarValue, const int size) |
| 1674 |
{ |
| 1675 |
scalarListPtr_ = vtkFloatArray::New(); |
| 1676 |
type_ = SCALARLIST; |
| 1677 |
vtkFloatArray& sl = *scalarListPtr_; |
| 1678 |
sl.SetNumberOfValues(size); |
| 1679 |
for(int i = 0; i < size; i++) |
| 1680 |
{ |
| 1681 |
sl.SetValue(i, scalarValue); |
| 1682 |
} |
| 1683 |
} |
| 1684 |
|
| 1685 |
// reads dimensionSet |
| 1686 |
void readDimensionSet(vtkFoamIOobject& io) |
| 1687 |
{ |
| 1688 |
const int nDims = 7; |
| 1689 |
labelListPtr_ = vtkIntArray::New(); |
| 1690 |
type_ = LABELLIST; |
| 1691 |
labelListPtr_->SetNumberOfValues(nDims); |
| 1692 |
for(int dimI = 0; dimI < nDims; dimI++) |
| 1693 |
{ |
| 1694 |
labelListPtr_->SetValue(dimI, io.readValue<int>()); |
| 1695 |
} |
| 1696 |
io.readExpecting(']'); |
| 1697 |
} |
| 1698 |
|
| 1699 |
// generic reader for nonuniform lists. requires size prefix of the |
| 1700 |
// list to be present in the stream if the format is binary. |
| 1701 |
template <vtkFoamToken::tokenType listType, typename traitsT> |
| 1702 |
void readNonuniformList(vtkFoamIOobject& io) |
| 1703 |
{ |
| 1704 |
vtkFoamToken currToken; |
| 1705 |
if(!io.read(currToken)) |
| 1706 |
{ |
| 1707 |
throw vtkFoamError() << "Unexpected EOF"; |
| 1708 |
} |
| 1709 |
traitsT list; |
| 1710 |
type_ = listType; |
| 1711 |
vtkObjectPtr_ = list.ptr(); |
| 1712 |
if(currToken.is<int>()) |
| 1713 |
{ |
| 1714 |
const int size = currToken.to<int>(); |
| 1715 |
if(size < 0) |
| 1716 |
{ |
| 1717 |
throw vtkFoamError() << "List size must not be negative: size = " |
| 1718 |
<< size; |
| 1719 |
} |
| 1720 |
list.ptr()->SetNumberOfTuples(size); |
| 1721 |
if(!io.read(currToken)) |
| 1722 |
{ |
| 1723 |
throw vtkFoamError() << "Unexpected EOF"; |
| 1724 |
} |
| 1725 |
// some objects have lists with only one element enclosed by {} |
| 1726 |
// e. g. simpleFoam/pitzDaily3Blocks/constant/polyMesh/faceZones |
| 1727 |
if(currToken == '{') |
| 1728 |
{ |
| 1729 |
list.readUniformValues(io, size); |
| 1730 |
io.readExpecting('}'); |
| 1731 |
return; |
| 1732 |
} |
| 1733 |
else if(currToken != '(') |
| 1734 |
{ |
| 1735 |
throw vtkFoamError() << "Expected '(', found " << currToken; |
| 1736 |
} |
| 1737 |
else if(io.format() == vtkFoamIOobject::ASCII) |
| 1738 |
{ |
| 1739 |
list.readAsciiList(io, size); |
| 1740 |
} |
| 1741 |
else |
| 1742 |
{ |
| 1743 |
if(size > 0) // avoid invalid access to ll.at(0) |
| 1744 |
{ |
| 1745 |
list.readBinaryList(io, size); |
| 1746 |
} |
| 1747 |
} |
| 1748 |
io.readExpecting(')'); |
| 1749 |
} |
| 1750 |
else if(currToken == '(') |
| 1751 |
{ |
| 1752 |
while(io.read(currToken) && currToken != ')') |
| 1753 |
{ |
| 1754 |
list.readValue(io, currToken); |
| 1755 |
} |
| 1756 |
list.ptr()->Squeeze(); |
| 1757 |
} |
| 1758 |
else |
| 1759 |
{ |
| 1760 |
throw vtkFoamError() << "Expected integer or '(', found " << currToken; |
| 1761 |
} |
| 1762 |
} |
| 1763 |
|
| 1764 |
// reads a list of labelLists. requires size prefix of the listList |
| 1765 |
// to be present. size of each sublist must also be present in the |
| 1766 |
// stream if the format is binary. |
| 1767 |
void readLabelListList(vtkFoamIOobject& io) |
| 1768 |
{ |
| 1769 |
vtkFoamToken currToken; |
| 1770 |
if(!io.read(currToken)) |
| 1771 |
{ |
| 1772 |
throw vtkFoamError() << "Unexpected EOF"; |
| 1773 |
} |
| 1774 |
if(currToken.type() == vtkFoamToken::LABEL) |
| 1775 |
{ |
| 1776 |
const int sizeI = currToken.to<int>(); |
| 1777 |
if(sizeI < 0) |
| 1778 |
{ |
| 1779 |
throw vtkFoamError() << "List size must not be negative: size = " |
| 1780 |
<< sizeI; |
| 1781 |
} |
| 1782 |
// gives initial guess for list size |
| 1783 |
labelListListPtr_ = new intVectorVector(sizeI, 4 * sizeI); |
| 1784 |
type_ = LABELLISTLIST; |
| 1785 |
io.readExpecting('('); |
| 1786 |
int bodyI = 0; |
| 1787 |
for(int i = 0; i < sizeI; i++) |
| 1788 |
{ |
| 1789 |
if(!io.read(currToken)) |
| 1790 |
{ |
| 1791 |
throw vtkFoamError() << "Unexpected EOF"; |
| 1792 |
} |
| 1793 |
if(currToken.type() == vtkFoamToken::LABEL) |
| 1794 |
{ |
| 1795 |
const int sizeJ = currToken.to<int>(); |
| 1796 |
if(sizeJ < 0) |
| 1797 |
{ |
| 1798 |
throw vtkFoamError() << "List size must not be negative: size = " |
| 1799 |
<< sizeJ; |
| 1800 |
} |
| 1801 |
if(bodyI + sizeJ > labelListListPtr_->bodySize()) |
| 1802 |
{ |
| 1803 |
const int newSize = labelListListPtr_->bodySize() + sizeJ; |
| 1804 |
labelListListPtr_->resizeBody(newSize); |
| 1805 |
} |
| 1806 |
io.readExpecting('('); |
| 1807 |
int *listI = labelListListPtr_->setIndex(i, bodyI); |
| 1808 |
if(io.format() == vtkFoamIOobject::ASCII) |
| 1809 |
{ |
| 1810 |
for(int j = 0; j < sizeJ; j++) |
| 1811 |
{ |
| 1812 |
listI[j] = io.readValue<int>(); |
| 1813 |
} |
| 1814 |
} |
| 1815 |
else |
| 1816 |
{ |
| 1817 |
if(sizeJ > 0) // avoid invalid reference to labelListI.at(0) |
| 1818 |
{ |
| 1819 |
io.read(reinterpret_cast<unsigned char*>(listI), |
| 1820 |
sizeJ * sizeof(int)); |
| 1821 |
} |
| 1822 |
} |
| 1823 |
bodyI += sizeJ; |
| 1824 |
io.readExpecting(')'); |
| 1825 |
} |
| 1826 |
else if(currToken == '(') |
| 1827 |
{ |
| 1828 |
labelListListPtr_->setIndex(i, bodyI); |
| 1829 |
while(io.read(currToken) && currToken != ')') |
| 1830 |
{ |
| 1831 |
if(currToken.type() != vtkFoamToken::LABEL) |
| 1832 |
{ |
| 1833 |
throw vtkFoamError() << "Expected an integer, found " |
| 1834 |
<< currToken; |
| 1835 |
} |
| 1836 |
if(bodyI >= labelListListPtr_->bodySize()) |
| 1837 |
{ |
| 1838 |
const int newSize = labelListListPtr_->bodySize() + 1; |
| 1839 |
labelListListPtr_->resizeBody(newSize); |
| 1840 |
} |
| 1841 |
labelListListPtr_->setValue(bodyI++, currToken.to<int>()); |
| 1842 |
} |
| 1843 |
} |
| 1844 |
else |
| 1845 |
{ |
| 1846 |
throw vtkFoamError() << "Expected integer or '(', found " |
| 1847 |
<< currToken; |
| 1848 |
} |
| 1849 |
} |
| 1850 |
// set the next index of the last element to calculate the last |
| 1851 |
// subarray size |
| 1852 |
labelListListPtr_->setIndex(sizeI, bodyI); |
| 1853 |
// shrink to the actually used size |
| 1854 |
labelListListPtr_->resizeBody(bodyI); |
| 1855 |
io.readExpecting(')'); |
| 1856 |
} |
| 1857 |
else |
| 1858 |
{ |
| 1859 |
throw vtkFoamError() << "Expected integer, found " << currToken; |
| 1860 |
} |
| 1861 |
} |
| 1862 |
}; |
| 1863 |
|
| 1864 |
template<> |
| 1865 |
void vtkOpenFOAMReader::vtkFoamEntryValue::listTraits<vtkFloatArray, float> |
| 1866 |
::readBinaryList(vtkFoamIOobject& io, const int size) |
| 1867 |
{ |
| 1868 |
for(int i = 0; i < size; i++) |
| 1869 |
{ |
| 1870 |
double buffer; |
| 1871 |
io.read(reinterpret_cast<unsigned char *>(&buffer), sizeof(double)); |
| 1872 |
ptr_->SetValue(i, static_cast<float>(buffer)); |
| 1873 |
} |
| 1874 |
} |
| 1875 |
|
| 1876 |
//----------------------------------------------------------------------------- |
| 1877 |
// class vtkFoamEntry |
| 1878 |
// a class that represents an entry of a dictionary. note that an |
| 1879 |
// entry can have more than one value. |
| 1880 |
struct vtkOpenFOAMReader::vtkFoamEntry |
| 1881 |
{ |
| 1882 |
private: |
| 1883 |
vtkStdString keyword_; |
| 1884 |
vtkstd::vector<vtkFoamEntryValue*> valuePtrs_; |
| 1885 |
vtkFoamDict *upperDictPtr_; |
| 1886 |
|
| 1887 |
vtkFoamEntry(); |
| 1888 |
|
| 1889 |
public: |
| 1890 |
vtkFoamEntry(vtkFoamDict *upperDictPtr): upperDictPtr_(upperDictPtr) {} |
| 1891 |
vtkFoamEntry(const vtkFoamEntry& entry, vtkFoamDict *upperDictPtr) |
| 1892 |
: keyword_(entry.keyword()), valuePtrs_(entry.size()), |
| 1893 |
upperDictPtr_(upperDictPtr) |
| 1894 |
{ |
| 1895 |
for(size_t valueI = 0; valueI < entry.size(); valueI++) |
| 1896 |
{ |
| 1897 |
valuePtrs_[valueI] = new vtkFoamEntryValue(entry.value(valueI), this); |
| 1898 |
} |
| 1899 |
} |
| 1900 |
|
| 1901 |
~vtkFoamEntry() { clear(); } |
| 1902 |
|
| 1903 |
void clear() |
| 1904 |
{ |
| 1905 |
for(size_t i = 0; i < valuePtrs_.size(); i++) |
| 1906 |
{ |
| 1907 |
delete valuePtrs_[i]; |
| 1908 |
} |
| 1909 |
valuePtrs_.clear(); |
| 1910 |
} |
| 1911 |
const vtkStdString& keyword() const { return keyword_; } |
| 1912 |
vtkStdString& keyword() { return keyword_; } |
| 1913 |
size_t size() const { return valuePtrs_.size(); } |
| 1914 |
// returns false if the number of the values is 0 to simplify things |
| 1915 |
bool found() const { return valuePtrs_.size() > 0; } |
| 1916 |
vtkFoamEntryValue& value(const int i) const { return *valuePtrs_[i]; } |
| 1917 |
vtkFoamEntryValue& firstValue() const { return *valuePtrs_[0]; } |
| 1918 |
vtkIntArray& labelList() const |
| 1919 |
{ return firstValue().labelList(); } |
| 1920 |
const intVectorVector& labelListList() const |
| 1921 |
{ return firstValue().labelListList(); } |
| 1922 |
vtkFloatArray& scalarList() |
| 1923 |
{ return firstValue().scalarList(); } |
| 1924 |
vtkFloatArray& vectorList() |
| 1925 |
{ return firstValue().vectorList(); } |
| 1926 |
vtkFoamDict& dictionary() // not using firstValue() for breaking constness |
| 1927 |
{ return valuePtrs_[0]->dictionary(); } |
| 1928 |
void *ptr() { return firstValue().ptr(); } |
| 1929 |
vtkFoamDict *upperDictPtr() { return upperDictPtr_; } |
| 1930 |
|
| 1931 |
vtkStdString toString() const |
| 1932 |
{ return found() ? firstValue().toString() : vtkStdString(); } |
| 1933 |
float toFloat() const |
| 1934 |
{ return found() ? firstValue().toFloat() : 0.0F; } |
| 1935 |
double toDouble() const |
| 1936 |
{ return found() ? firstValue().toDouble() : 0.0; } |
| 1937 |
int toInt() const |
| 1938 |
{ return found() ? firstValue().toInt() : 0; } |
| 1939 |
|
| 1940 |
void readDictionary(vtkFoamIOobject& io) |
| 1941 |
{ |
| 1942 |
valuePtrs_.push_back(new vtkFoamEntryValue(this)); |
| 1943 |
valuePtrs_.back()->readDictionary(io, vtkFoamToken()); |
| 1944 |
} |
| 1945 |
|
| 1946 |
// read values of an entry |
| 1947 |
void read(vtkFoamIOobject& io); |
| 1948 |
}; |
| 1949 |
|
| 1950 |
//----------------------------------------------------------------------------- |
| 1951 |
// class vtkFoamDict |
| 1952 |
// a class that holds a FoamFile data structure |
| 1953 |
struct vtkOpenFOAMReader::vtkFoamDict: public vtkFoamEntryValue |
| 1954 |
{ |
| 1955 |
private: |
| 1956 |
vtkstd::vector<vtkFoamEntry*> entryPtrs_; |
| 1957 |
vtkFoamEntry *dummyEntryPtr_; |
| 1958 |
vtkFoamDict *upperDictPtr_; |
| 1959 |
|
| 1960 |
vtkFoamDict(const vtkFoamDict &); |
| 1961 |
|
| 1962 |
public: |
| 1963 |
vtkFoamDict(vtkFoamDict *upperDictPtr = NULL) |
| 1964 |
: vtkFoamEntryValue(NULL), dummyEntryPtr_(NULL), upperDictPtr_(upperDictPtr) |
| 1965 |
{ dictPtr_ = NULL; } // avoid destruction in vtkFoamEntryValue::clear() |
| 1966 |
vtkFoamDict(vtkFoamDict& dict, vtkFoamDict *upperDictPtr) |
| 1967 |
: vtkFoamEntryValue(dict, NULL), entryPtrs_(dict.size()), |
| 1968 |
dummyEntryPtr_(NULL), upperDictPtr_(upperDictPtr) |
| 1969 |
{ |
| 1970 |
if(dict.type() == vtkFoamToken::DICTIONARY) |
| 1971 |
{ |
| 1972 |
for(size_t entryI = 0; entryI < dict.size(); entryI++) |
| 1973 |
{ |
| 1974 |
entryPtrs_[entryI] = new vtkFoamEntry(dict.entry(entryI), this); |
| 1975 |
} |
| 1976 |
} |
| 1977 |
} |
| 1978 |
|
| 1979 |
~vtkFoamDict() |
| 1980 |
{ |
| 1981 |
if(type_ == DICTIONARY) |
| 1982 |
{ |
| 1983 |
for(size_t i = 0; i < entryPtrs_.size(); i++) |
| 1984 |
{ |
| 1985 |
delete entryPtrs_[i]; |
| 1986 |
} |
| 1987 |
} |
| 1988 |
delete dummyEntryPtr_; |
| 1989 |
} |
| 1990 |
|
| 1991 |
size_t size() const { return entryPtrs_.size(); } |
| 1992 |
vtkFoamDict *upperDictPtr() { return upperDictPtr_; } |
| 1993 |
const vtkFoamEntry& entry(const int i) const { return *entryPtrs_[i]; } |
| 1994 |
vtkFoamEntry& entry(const int i) { return *entryPtrs_[i]; } |
| 1995 |
vtkFoamEntry& lookup(const vtkStdString& keyword) |
| 1996 |
{ |
| 1997 |
if(type_ == DICTIONARY) |
| 1998 |
{ |
| 1999 |
for(size_t i = 0; i < entryPtrs_.size(); i++) |
| 2000 |
{ |
| 2001 |
if(entryPtrs_[i]->keyword() == keyword) // found |
| 2002 |
{ |
| 2003 |
return *entryPtrs_[i]; |
| 2004 |
} |
| 2005 |
} |
| 2006 |
} |
| 2007 |
|
| 2008 |
// not found |
| 2009 |
if(dummyEntryPtr_ == NULL) |
| 2010 |
{ |
| 2011 |
dummyEntryPtr_ = new vtkFoamEntry(NULL); |
| 2012 |
} |
| 2013 |
return *dummyEntryPtr_; |
| 2014 |
} |
| 2015 |
|
| 2016 |
// reads a FoamFile or a subdictionary. if the stream to be read is |
| 2017 |
// a subdictionary the preceding '{' is assumed to have already been |
| 2018 |
// thrown away. |
| 2019 |
bool read(vtkFoamIOobject& io, const bool isSubDictionary = false, |
| 2020 |
const vtkFoamToken& firstToken = vtkFoamToken()) |
| 2021 |
{ |
| 2022 |
try |
| 2023 |
{ |
| 2024 |
vtkFoamToken currToken; |
| 2025 |
if(firstToken.type() == vtkFoamToken::UNDEFINED) |
| 2026 |
{ |
| 2027 |
if(!isSubDictionary) |
| 2028 |
{ |
| 2029 |
if(io.className() == "scalarField") // lagrangian scalars |
| 2030 |
{ |
| 2031 |
readNonuniformList<SCALARLIST, listTraits<vtkFloatArray, float> >( |
| 2032 |
io); |
| 2033 |
return true; |
| 2034 |
} |
| 2035 |
// polyMesh/points, lagrangian vectors |
| 2036 |
else if(io.className() == "sphericalTensorField") |
| 2037 |
{ |
| 2038 |
readNonuniformList<VECTORLIST, |
| 2039 |
vectorListTraits<vtkFloatArray, float, 1, false> >(io); |
| 2040 |
return true; |
| 2041 |
} |
| 2042 |
else if(io.className() == "vectorField") |
| 2043 |
{ |
| 2044 |
readNonuniformList<VECTORLIST, |
| 2045 |
vectorListTraits<vtkFloatArray, float, 3, false> >(io); |
| 2046 |
return true; |
| 2047 |
} |
| 2048 |
else if(io.className() == "symmTensorField") |
| 2049 |
{ |
| 2050 |
readNonuniformList<VECTORLIST, |
| 2051 |
vectorListTraits<vtkFloatArray, float, 6, false> >(io); |
| 2052 |
return true; |
| 2053 |
} |
| 2054 |
else if(io.className() == "tensorField") |
| 2055 |
{ |
| 2056 |
readNonuniformList<VECTORLIST, |
| 2057 |
vectorListTraits<vtkFloatArray, float, 9, false> >(io); |
| 2058 |
return true; |
| 2059 |
} |
| 2060 |
// lagrangian positions. there are many concrete class names |
| 2061 |
// e. g. Cloud<parcel>, basicKinematicCloud etc. |
| 2062 |
else if(io.className().find("Cloud") != vtkStdString::npos |
| 2063 |
&& io.objectName() == "positions") |
| 2064 |
{ |
| 2065 |
readNonuniformList<VECTORLIST, |
| 2066 |
vectorListTraits<vtkFloatArray, float, 3, true> >(io); |
| 2067 |
return true; |
| 2068 |
} |
| 2069 |
else if(io.className() == "faceList") // polyMesh/faces |
| 2070 |
{ |
| 2071 |
readLabelListList(io); |
| 2072 |
return true; |
| 2073 |
} |
| 2074 |
else if(io.className() == "labelList") // polyMesh/{owner|neighbour} |
| 2075 |
{ |
| 2076 |
readNonuniformList<LABELLIST, listTraits<vtkIntArray, int> >(io); |
| 2077 |
return true; |
| 2078 |
} |
| 2079 |
} |
| 2080 |
|
| 2081 |
// read the first token |
| 2082 |
if(!io.read(currToken)) |
| 2083 |
{ |
| 2084 |
throw vtkFoamError() << "Unexpected EOF"; |
| 2085 |
} |
| 2086 |
|
| 2087 |
// list of dictionaries is read as a usual dictionary |
| 2088 |
// polyMesh/boundary, point/face/cell-Zones |
| 2089 |
if(!isSubDictionary && currToken.type() == vtkFoamToken::LABEL) |
| 2090 |
{ |
| 2091 |
io.readExpecting('('); |
| 2092 |
if(currToken.to<int>() > 0) |
| 2093 |
{ |
| 2094 |
if(!io.read(currToken)) |
| 2095 |
{ |
| 2096 |
throw vtkFoamError() << "Unexpected EOF"; |
| 2097 |
} |
| 2098 |
// continue to read as a usual dictionary |
| 2099 |
} |
| 2100 |
else // return as empty dictionary |
| 2101 |
{ |
| 2102 |
io.readExpecting(')'); |
| 2103 |
type_ = DICTIONARY; |
| 2104 |
return true; |
| 2105 |
} |
| 2106 |
} |
| 2107 |
// some boundary files does not have the number of boundary |
| 2108 |
// patches (e.g. settlingFoam/tank3D). in this case we need to |
| 2109 |
// explicitly read the file as a dictionary. |
| 2110 |
else if(!isSubDictionary && currToken == '(' |
| 2111 |
&& io.className() == "polyBoundaryMesh") // polyMesh/boundary |
| 2112 |
{ |
| 2113 |
if(!io.read(currToken)) // read the first keyword |
| 2114 |
{ |
| 2115 |
throw vtkFoamError() << "Unexpected EOF"; |
| 2116 |
} |
| 2117 |
if(currToken == ')') // return as empty dictionary |
| 2118 |
{ |
| 2119 |
type_ = DICTIONARY; |
| 2120 |
return true; |
| 2121 |
} |
| 2122 |
} |
| 2123 |
// the following two else-if clauses are for an exceptional |
| 2124 |
// expression of `LABEL{LABELorSCALAR}' without type prefix |
| 2125 |
// (e. g. `2{-0}' in mixedRhoE B.C. in |
| 2126 |
// rhopSonicFoam/shockTube) |
| 2127 |
else if(isSubDictionary && currToken.type() == vtkFoamToken::LABEL) |
| 2128 |
{ |
| 2129 |
vtkFoamToken::operator=(currToken.to<int>()); |
| 2130 |
type_ = UNIFORMLABELLIST; |
| 2131 |
io.readExpecting('}'); |
| 2132 |
return true; |
| 2133 |
} |
| 2134 |
else if(isSubDictionary && currToken.type() == vtkFoamToken::SCALAR) |
| 2135 |
{ |
| 2136 |
vtkFoamToken::operator=(currToken.to<float>()); |
| 2137 |
type_ = UNIFORMSCALARLIST; |
| 2138 |
io.readExpecting('}'); |
| 2139 |
return true; |
| 2140 |
} |
| 2141 |
// return as empty dictionary |
| 2142 |
else if(isSubDictionary && currToken == '}') |
| 2143 |
{ |
| 2144 |
type_ = DICTIONARY; |
| 2145 |
return true; |
| 2146 |
} |
| 2147 |
} |
| 2148 |
// if firstToken is given as string set read the following stream |
| 2149 |
// as subdictionary |
| 2150 |
else if(firstToken.type() == vtkFoamToken::STRING) |
| 2151 |
{ |
| 2152 |
type_ = DICTIONARY; |
| 2153 |
entryPtrs_.push_back(new vtkFoamEntry(this)); |
| 2154 |
entryPtrs_.back()->keyword() = firstToken.toString(); |
| 2155 |
entryPtrs_.back()->readDictionary(io); |
| 2156 |
if(!io.read(currToken) || currToken == '}' || currToken == ')') |
| 2157 |
{ |
| 2158 |
return true; |
| 2159 |
} |
| 2160 |
} |
| 2161 |
else // quite likely an identifier |
| 2162 |
{ |
| 2163 |
currToken = firstToken; |
| 2164 |
} |
| 2165 |
|
| 2166 |
if(currToken == ';' || currToken.type() == vtkFoamToken::STRING |
| 2167 |
|| currToken.type() == vtkFoamToken::IDENTIFIER) // general dictionary |
| 2168 |
{ |
| 2169 |
// type must be set first so that lookup() works |
| 2170 |
type_ = DICTIONARY; |
| 2171 |
do |
| 2172 |
{ |
| 2173 |
if(currToken.type() == vtkFoamToken::STRING) |
| 2174 |
{ |
| 2175 |
vtkFoamEntry& previousEntry = lookup(currToken.toString()); |
| 2176 |
if(previousEntry.found()) |
| 2177 |
{ |
| 2178 |
if(io.getInputMode() == vtkFoamFile::INPUT_MODE_MERGE) |
| 2179 |
{ |
| 2180 |
if(previousEntry.firstValue().type() |
| 2181 |
== vtkFoamToken::DICTIONARY) |
| 2182 |
{ |
| 2183 |
io.readExpecting('{'); |
| 2184 |
previousEntry.firstValue().dictionary().read(io, true); |
| 2185 |
} |
| 2186 |
else |
| 2187 |
{ |
| 2188 |
previousEntry.clear(); |
| 2189 |
previousEntry.read(io); |
| 2190 |
} |
| 2191 |
} |
| 2192 |
else if(io.getInputMode() == vtkFoamFile::INPUT_MODE_OVERWRITE) |
| 2193 |
{ |
| 2194 |
previousEntry.clear(); |
| 2195 |
previousEntry.read(io); |
| 2196 |
} |
| 2197 |
else // INPUT_MODE_ERROR |
| 2198 |
{ |
| 2199 |
throw vtkFoamError() << "Found duplicated entries with keyword " |
| 2200 |
<< currToken.toString(); |
| 2201 |
} |
| 2202 |
} |
| 2203 |
else |
| 2204 |
{ |
| 2205 |
entryPtrs_.push_back(new vtkFoamEntry(this)); |
| 2206 |
entryPtrs_.back()->keyword() = currToken.toString(); |
| 2207 |
entryPtrs_.back()->read(io); |
| 2208 |
} |
| 2209 |
|
| 2210 |
if(currToken == "FoamFile") |
| 2211 |
{ |
| 2212 |
// delete the FoamFile header subdictionary entry |
| 2213 |
delete entryPtrs_.back(); |
| 2214 |
entryPtrs_.pop_back(); |
| 2215 |
} |
| 2216 |
else if(currToken == "include") |
| 2217 |
{ |
| 2218 |
// include the named file. Exiting the included file at |
| 2219 |
// EOF will be handled automatically by |
| 2220 |
// vtkFoamFile::closeIncludedFile() |
| 2221 |
if(entryPtrs_.back()->firstValue().type() != vtkFoamToken::STRING) |
| 2222 |
{ |
| 2223 |
throw vtkFoamError() |
| 2224 |
<< "Expected string as the file name to be included, found " |
| 2225 |
<< entryPtrs_.back()->firstValue(); |
| 2226 |
} |
| 2227 |
vtkStdString includeFileName(entryPtrs_.back()->toString()); |
| 2228 |
delete entryPtrs_.back(); |
| 2229 |
entryPtrs_.pop_back(); |
| 2230 |
io.includeFile(includeFileName, io.filePath()); |
| 2231 |
} |
| 2232 |
} |
| 2233 |
else if(currToken.type() == vtkFoamToken::IDENTIFIER) |
| 2234 |
{ |
| 2235 |
// substitute identifier |
| 2236 |
const vtkStdString identifier(currToken.toIdentifier()); |
| 2237 |
|
| 2238 |
for(vtkFoamDict *uDictPtr = this;;) |
| 2239 |
{ |
| 2240 |
const vtkFoamEntry& |
| 2241 |
identifiedEntry = uDictPtr->lookup(identifier); |
| 2242 |
|
| 2243 |
if(identifiedEntry.found()) |
| 2244 |
{ |
| 2245 |
if(identifiedEntry.firstValue().type() |
| 2246 |
!= vtkFoamToken::DICTIONARY) |
| 2247 |
{ |
| 2248 |
throw vtkFoamError() |
| 2249 |
<< "Expected dictionary for substituting entry " |
| 2250 |
<< identifier; |
| 2251 |
} |
| 2252 |
vtkFoamDict& identifiedDict |
| 2253 |
= identifiedEntry.firstValue().dictionary(); |
| 2254 |
for(size_t entryI = 0; entryI < identifiedDict.size(); entryI++) |
| 2255 |
{ |
| 2256 |
// I think #inputMode handling should be done here |
| 2257 |
// as well, but the genuine FoamFile parser for OF |
| 2258 |
// 1.5 does not seem to be doing it. |
| 2259 |
entryPtrs_.push_back( |
| 2260 |
new vtkFoamEntry(identifiedDict.entry(entryI), this)); |
| 2261 |
} |
| 2262 |
break; |
| 2263 |
} |
| 2264 |
else |
| 2265 |
{ |
| 2266 |
uDictPtr = uDictPtr->upperDictPtr(); |
| 2267 |
if(uDictPtr == NULL) |
| 2268 |
{ |
| 2269 |
throw vtkFoamError() << "Substituting entry " << identifier |
| 2270 |
<< " not found"; |
| 2271 |
} |
| 2272 |
} |
| 2273 |
} |
| 2274 |
} |
| 2275 |
// skip empty entry only with ';' |
| 2276 |
} while(io.read(currToken) |
| 2277 |
&& (currToken.type() == vtkFoamToken::STRING |
| 2278 |
|| currToken.type() == vtkFoamToken::IDENTIFIER || currToken == ';')); |
| 2279 |
|
| 2280 |
if(currToken.type() == vtkFoamToken::ERROR || currToken == '}' |
| 2281 |
|| currToken == ')') |
| 2282 |
{ |
| 2283 |
return true; |
| 2284 |
} |
| 2285 |
type_ = UNDEFINED; |
| 2286 |
throw vtkFoamError() |
| 2287 |
<< "Expected keyword, closing brace, ';' or EOF, found " << currToken; |
| 2288 |
} |
| 2289 |
throw vtkFoamError() << "Expected keyword or identifier, found " |
| 2290 |
<< currToken; |
| 2291 |
} |
| 2292 |
catch(vtkFoamError& e) |
| 2293 |
{ |
| 2294 |
if(isSubDictionary) |
| 2295 |
{ |
| 2296 |
throw; |
| 2297 |
} |
| 2298 |
else |
| 2299 |
{ |
| 2300 |
io.setError(e); |
| 2301 |
return false; |
| 2302 |
} |
| 2303 |
} |
| 2304 |
} |
| 2305 |
}; |
| 2306 |
|
| 2307 |
void vtkOpenFOAMReader::vtkFoamIOobject::readHeader() |
| 2308 |
{ |
| 2309 |
vtkFoamToken firstToken; |
| 2310 |
|
| 2311 |
readExpecting("FoamFile"); |
| 2312 |
readExpecting('{'); |
| 2313 |
|
| 2314 |
vtkFoamDict headerDict; |
| 2315 |
// throw exception in case of error |
| 2316 |
headerDict.read(*this, true, vtkFoamToken()); |
| 2317 |
|
| 2318 |
const vtkFoamEntry& formatEntry = headerDict.lookup("format"); |
| 2319 |
if(!formatEntry.found()) |
| 2320 |
{ |
| 2321 |
throw vtkFoamError() |
| 2322 |
<< "format entry (binary/ascii) not found in FoamFile header"; |
| 2323 |
} |
| 2324 |
// case does matter (e. g. "BINARY" is treated as ascii) |
| 2325 |
// cf. src/OpenFOAM/db/IOstreams/IOstreams/IOstream.C |
| 2326 |
format_ = (formatEntry.toString() == "binary" ? BINARY : ASCII); |
| 2327 |
|
| 2328 |
const vtkFoamEntry& classEntry = headerDict.lookup("class"); |
| 2329 |
if(!classEntry.found()) |
| 2330 |
{ |
| 2331 |
throw vtkFoamError() << "class name not found in FoamFile header"; |
| 2332 |
} |
| 2333 |
headerClassName_ = classEntry.toString(); |
| 2334 |
|
| 2335 |
const vtkFoamEntry& objectEntry = headerDict.lookup("object"); |
| 2336 |
if(!objectEntry.found()) |
| 2337 |
{ |
| 2338 |
throw vtkFoamError() << "object name not found in FoamFile header"; |
| 2339 |
} |
| 2340 |
objectName_ = objectEntry.toString(); |
| 2341 |
} |
| 2342 |
|
| 2343 |
vtkOpenFOAMReader::vtkFoamEntryValue::vtkFoamEntryValue( |
| 2344 |
vtkFoamEntryValue& value, vtkFoamEntry *upperEntryPtr) |
| 2345 |
: vtkFoamToken(value), isUniform_(value.isUniform()), managed_(true), |
| 2346 |
upperEntryPtr_(upperEntryPtr) |
| 2347 |
{ |
| 2348 |
switch(type_) |
| 2349 |
{ |
| 2350 |
case LABELLIST: case SCALARLIST: case VECTORLIST: case STRINGLIST: |
| 2351 |
vtkObjectPtr_ = value.toVTKObject(); |
| 2352 |
vtkObjectPtr_->Register(0); // increase reference count +1 |
| 2353 |
break; |
| 2354 |
case LABELLISTLIST: |
| 2355 |
labelListListPtr_ = new intVectorVector(*value.labelListListPtr_); |
| 2356 |
break; |
| 2357 |
case ENTRYVALUELIST: |
| 2358 |
{ |
| 2359 |
const int nValues = value.entryValuePtrs_->size(); |
| 2360 |
entryValuePtrs_ = new vtkstd::vector<vtkFoamEntryValue*>(nValues); |
| 2361 |
for(int valueI = 0; valueI < nValues; valueI++) |
| 2362 |
{ |
| 2363 |
entryValuePtrs_->operator[](valueI) = new vtkFoamEntryValue( |
| 2364 |
*value.entryValuePtrs_->operator[](valueI), upperEntryPtr_); |
| 2365 |
} |
| 2366 |
} |
| 2367 |
break; |
| 2368 |
case DICTIONARY: |
| 2369 |
// upperEntryPtr_ is null when called from vtkFoamDict constructor |
| 2370 |
if(upperEntryPtr_ != NULL) |
| 2371 |
{ |
| 2372 |
dictPtr_ |
| 2373 |
= new vtkFoamDict(*value.dictPtr_, upperEntryPtr_->upperDictPtr()); |
| 2374 |
} |
| 2375 |
else |
| 2376 |
{ |
| 2377 |
dictPtr_ = NULL; |
| 2378 |
} |
| 2379 |
break; |
| 2380 |
case EMPTYLIST: |
| 2381 |
break; |
| 2382 |
} |
| 2383 |
} |
| 2384 |
|
| 2385 |
void vtkOpenFOAMReader::vtkFoamEntryValue::clear() |
| 2386 |
{ |
| 2387 |
if(managed_) |
| 2388 |
{ |
| 2389 |
switch(type_) |
| 2390 |
{ |
| 2391 |
case LABELLIST: case SCALARLIST: case VECTORLIST: case STRINGLIST: |
| 2392 |
vtkObjectPtr_->Delete(); |
| 2393 |
break; |
| 2394 |
case LABELLISTLIST: |
| 2395 |
delete labelListListPtr_; |
| 2396 |
break; |
| 2397 |
case ENTRYVALUELIST: |
| 2398 |
for(size_t valueI = 0; valueI < entryValuePtrs_->size() ; valueI++) |
| 2399 |
{ |
| 2400 |
delete entryValuePtrs_->operator[](valueI); |
| 2401 |
} |
| 2402 |
delete entryValuePtrs_; |
| 2403 |
break; |
| 2404 |
case DICTIONARY: |
| 2405 |
delete dictPtr_; |
| 2406 |
break; |
| 2407 |
} |
| 2408 |
} |
| 2409 |
} |
| 2410 |
|
| 2411 |
// general-purpose list reader - guess the type of the list and read |
| 2412 |
// it. only supports ascii format and assumes the preceding '(' has |
| 2413 |
// already been thrown away. the reader supports nested list with |
| 2414 |
// variable lengths (e. g. `((token token) (token token token)).' |
| 2415 |
// also supports compound of tokens and lists (e. g. `((token token) |
| 2416 |
// token)') only if a list comes as the first value. |
| 2417 |
void vtkOpenFOAMReader::vtkFoamEntryValue::readList(vtkFoamIOobject& io) |
| 2418 |
{ |
| 2419 |
vtkFoamToken currToken; |
| 2420 |
io.read(currToken); |
| 2421 |
|
| 2422 |
// initial guess of the list type |
| 2423 |
if(currToken.type() == vtkFoamToken::LABEL) |
| 2424 |
{ |
| 2425 |
// if the first token is of type LABEL it might be either an element of |
| 2426 |
// a labelList or the size of a sublist so proceed to the next token |
| 2427 |
vtkFoamToken nextToken; |
| 2428 |
if(!io.read(nextToken)) |
| 2429 |
{ |
| 2430 |
throw vtkFoamError() << "Unexpected EOF"; |
| 2431 |
} |
| 2432 |
if(nextToken.type() == vtkFoamToken::LABEL) |
| 2433 |
{ |
| 2434 |
labelListPtr_ = vtkIntArray::New(); |
| 2435 |
labelListPtr_->InsertNextValue(currToken.to<int>()); |
| 2436 |
labelListPtr_->InsertNextValue(nextToken.to<int>()); |
| 2437 |
type_ = LABELLIST; |
| 2438 |
} |
| 2439 |
else if(nextToken.type() == vtkFoamToken::SCALAR) |
| 2440 |
{ |
| 2441 |
scalarListPtr_ = vtkFloatArray::New(); |
| 2442 |
scalarListPtr_->InsertNextValue(currToken.to<float>()); |
| 2443 |
scalarListPtr_->InsertNextValue(nextToken.to<float>()); |
| 2444 |
type_ = SCALARLIST; |
| 2445 |
} |
| 2446 |
else if(nextToken == '(') // list of list: read recursively |
| 2447 |
{ |
| 2448 |
entryValuePtrs_ = new vtkstd::vector<vtkFoamEntryValue*>; |
| 2449 |
entryValuePtrs_->push_back(new vtkFoamEntryValue(upperEntryPtr_)); |
| 2450 |
entryValuePtrs_->back()->readList(io); |
| 2451 |
type_ = ENTRYVALUELIST; |
| 2452 |
} |
| 2453 |
else if(nextToken == ')') // list with only one label element |
| 2454 |
{ |
| 2455 |
labelListPtr_ = vtkIntArray::New(); |
| 2456 |
labelListPtr_->SetNumberOfValues(1); |
| 2457 |
labelListPtr_->SetValue(0, currToken.to<int>()); |
| 2458 |
type_ = LABELLIST; |
| 2459 |
return; |
| 2460 |
} |
| 2461 |
else |
| 2462 |
{ |
| 2463 |
throw vtkFoamError() << "Expected number, '(' or ')', found " |
| 2464 |
<< nextToken; |
| 2465 |
} |
| 2466 |
} |
| 2467 |
else if(currToken.type() == vtkFoamToken::SCALAR) |
| 2468 |
{ |
| 2469 |
scalarListPtr_ = vtkFloatArray::New(); |
| 2470 |
scalarListPtr_->InsertNextValue(currToken.to<float>()); |
| 2471 |
type_ = SCALARLIST; |
| 2472 |
} |
| 2473 |
// if the first word is a string we have to read another token to determine |
| 2474 |
// if the first word is a keyword for the following dictionary |
| 2475 |
else if(currToken.type() == vtkFoamToken::STRING) |
| 2476 |
{ |
| 2477 |
vtkFoamToken nextToken; |
| 2478 |
if(!io.read(nextToken)) |
| 2479 |
{ |
| 2480 |
throw vtkFoamError() << "Unexpected EOF"; |
| 2481 |
} |
| 2482 |
if(nextToken.type() == vtkFoamToken::STRING) // list of strings |
| 2483 |
{ |
| 2484 |
stringListPtr_ = vtkStringArray::New(); |
| 2485 |
stringListPtr_->InsertNextValue(currToken.toString()); |
| 2486 |
stringListPtr_->InsertNextValue(nextToken.toString()); |
| 2487 |
type_ = STRINGLIST; |
| 2488 |
} |
| 2489 |
// dictionary with the already read stringToken as the first keyword |
| 2490 |
else if(nextToken == '{') |
| 2491 |
{ |
| 2492 |
if(currToken.toString() == "") |
| 2493 |
{ |
| 2494 |
throw "Empty string is invalid as a keyword for dictionary entry"; |
| 2495 |
} |
| 2496 |
readDictionary(io, currToken); |
| 2497 |
// the dictionary read as list has the entry terminator ';' so |
| 2498 |
// we have to skip it |
| 2499 |
return; |
| 2500 |
} |
| 2501 |
else if(nextToken == ')') // list with only one string element |
| 2502 |
{ |
| 2503 |
stringListPtr_ = vtkStringArray::New(); |
| 2504 |
stringListPtr_->SetNumberOfValues(1); |
| 2505 |
stringListPtr_->SetValue(0, currToken.toString()); |
| 2506 |
type_ = STRINGLIST; |
| 2507 |
return; |
| 2508 |
} |
| 2509 |
else |
| 2510 |
{ |
| 2511 |
throw vtkFoamError() << "Expected string, '{' or ')', found " |
| 2512 |
<< nextToken; |
| 2513 |
} |
| 2514 |
} |
| 2515 |
else if(currToken == '(') // list of lists: read recursively |
| 2516 |
{ |
| 2517 |
entryValuePtrs_ = new vtkstd::vector<vtkFoamEntryValue*>; |
| 2518 |
entryValuePtrs_->push_back(new vtkFoamEntryValue(upperEntryPtr_)); |
| 2519 |
entryValuePtrs_->back()->readList(io); |
| 2520 |
// read all the following values as arbitrary entryValues |
| 2521 |
// the alphaContactAngle b.c. in multiphaseInterFoam/damBreak4phase |
| 2522 |
// reaquires this treatment (reading by readList() is not enough) |
| 2523 |
do |
| 2524 |
{ |
| 2525 |
entryValuePtrs_->push_back(new vtkFoamEntryValue(upperEntryPtr_)); |
| 2526 |
entryValuePtrs_->back()->read(io); |
| 2527 |
} |
| 2528 |
while(*entryValuePtrs_->back() != ')' && *entryValuePtrs_->back() != '}' |
| 2529 |
&& *entryValuePtrs_->back() != ';'); |
| 2530 |
|
| 2531 |
if(*entryValuePtrs_->back() != ')') |
| 2532 |
{ |
| 2533 |
throw vtkFoamError() << "Expected ')' before " |
| 2534 |
<< *entryValuePtrs_->back(); |
| 2535 |
} |
| 2536 |
|
| 2537 |
// delete ')' |
| 2538 |
delete entryValuePtrs_->back(); |
| 2539 |
entryValuePtrs_->pop_back(); |
| 2540 |
type_ = ENTRYVALUELIST; |
| 2541 |
return; |
| 2542 |
} |
| 2543 |
else if(currToken == ')') // empty list |
| 2544 |
{ |
| 2545 |
type_ = EMPTYLIST; |
| 2546 |
return; |
| 2547 |
} |
| 2548 |
// FIXME: may (or may not) need identifier handling |
| 2549 |
|
| 2550 |
while(io.read(currToken) && currToken != ')') |
| 2551 |
{ |
| 2552 |
if(type_ == LABELLIST) |
| 2553 |
{ |
| 2554 |
if(currToken.type() == vtkFoamToken::SCALAR) // switch to scalarList |
| 2555 |
{ |
| 2556 |
// labelListPtr_ and scalarListPtr_ are packed into a single union so |
| 2557 |
// we need a temprary pointer |
| 2558 |
vtkFloatArray* slPtr = vtkFloatArray::New(); |
| 2559 |
const int size = labelListPtr_->GetNumberOfTuples(); |
| 2560 |
slPtr->SetNumberOfValues(size + 1); |
| 2561 |
for(int i = 0; i < size; i++) |
| 2562 |
{ |
| 2563 |
slPtr->SetValue(i, static_cast<float>(labelListPtr_->GetValue(i))); |
| 2564 |
} |
| 2565 |
labelListPtr_->Delete(); |
| 2566 |
slPtr->SetValue(size, currToken.to<float>()); |
| 2567 |
scalarListPtr_ = slPtr; // copy after labelListPtr_ is deleted |
| 2568 |
type_ = SCALARLIST; |
| 2569 |
} |
| 2570 |
else if(currToken.type() == vtkFoamToken::LABEL) |
| 2571 |
{ |
| 2572 |
labelListPtr_->InsertNextValue(currToken.to<int>()); |
| 2573 |
} |
| 2574 |
else |
| 2575 |
{ |
| 2576 |
throw vtkFoamError() << "Expected a number, found " << currToken; |
| 2577 |
} |
| 2578 |
} |
| 2579 |
else if(type_ == SCALARLIST) |
| 2580 |
{ |
| 2581 |
if(currToken.is<float>()) |
| 2582 |
{ |
| 2583 |
scalarListPtr_->InsertNextValue(currToken.to<float>()); |
| 2584 |
} |
| 2585 |
else |
| 2586 |
{ |
| 2587 |
throw vtkFoamError() << "Expected a number, found " << currToken; |
| 2588 |
} |
| 2589 |
} |
| 2590 |
else if(type_ == STRINGLIST) |
| 2591 |
{ |
| 2592 |
if(currToken.type() == vtkFoamToken::STRING) |
| 2593 |
{ |
| 2594 |
stringListPtr_->InsertNextValue(currToken.toString()); |
| 2595 |
} |
| 2596 |
else |
| 2597 |
{ |
| 2598 |
throw vtkFoamError() << "Expected a string, found " << currToken; |
| 2599 |
} |
| 2600 |
} |
| 2601 |
else if(type_ == ENTRYVALUELIST) |
| 2602 |
{ |
| 2603 |
if(currToken.type() == vtkFoamToken::LABEL) |
| 2604 |
{ |
| 2605 |
// skip the number of elements to make things simple |
| 2606 |
if(!io.read(currToken)) |
| 2607 |
{ |
| 2608 |
throw vtkFoamError() << "Unexpected EOF"; |
| 2609 |
} |
| 2610 |
} |
| 2611 |
if(currToken != '(') |
| 2612 |
{ |
| 2613 |
throw vtkFoamError() << "Expected '(', found " << currToken; |
| 2614 |
} |
| 2615 |
entryValuePtrs_->push_back(new vtkFoamEntryValue(upperEntryPtr_)); |
| 2616 |
entryValuePtrs_->back()->readList(io); |
| 2617 |
} |
| 2618 |
else |
| 2619 |
{ |
| 2620 |
throw vtkFoamError() << "Unexpected token " << currToken; |
| 2621 |
} |
| 2622 |
} |
| 2623 |
|
| 2624 |
if(type_ == LABELLIST) |
| 2625 |
{ |
| 2626 |
labelListPtr_->Squeeze(); |
| 2627 |
} |
| 2628 |
else if(type_ == SCALARLIST) |
| 2629 |
{ |
| 2630 |
scalarListPtr_->Squeeze(); |
| 2631 |
} |
| 2632 |
else if(type_ == STRINGLIST) |
| 2633 |
{ |
| 2634 |
stringListPtr_->Squeeze(); |
| 2635 |
} |
| 2636 |
} |
| 2637 |
|
| 2638 |
// a list of dictionaries is actually read as a dictionary |
| 2639 |
void vtkOpenFOAMReader::vtkFoamEntryValue::readDictionary(vtkFoamIOobject& io, |
| 2640 |
const vtkFoamToken& firstKeyword) |
| 2641 |
{ |
| 2642 |
dictPtr_ = new vtkFoamDict(upperEntryPtr_->upperDictPtr()); |
| 2643 |
type_ = DICTIONARY; |
| 2644 |
dictPtr_->read(io, true, firstKeyword); |
| 2645 |
} |
| 2646 |
|
| 2647 |
// guess the type of the given entry value and read it |
| 2648 |
void vtkOpenFOAMReader::vtkFoamEntryValue::read(vtkFoamIOobject& io) |
| 2649 |
{ |
| 2650 |
vtkFoamToken currToken; |
| 2651 |
if(!io.read(currToken)) |
| 2652 |
{ |
| 2653 |
throw vtkFoamError() << "Unexpected EOF"; |
| 2654 |
} |
| 2655 |
|
| 2656 |
if(currToken == '{') |
| 2657 |
{ |
| 2658 |
readDictionary(io, vtkFoamToken()); |
| 2659 |
return; |
| 2660 |
} |
| 2661 |
// for reading sublist from vtkFoamEntryValue::readList() or there |
| 2662 |
// are cases where lists without the (non)uniform keyword appear |
| 2663 |
// (e. g. coodles/pitsDaily/0/U, uniformFixedValue b.c.) |
| 2664 |
else if(currToken == '(') |
| 2665 |
{ |
| 2666 |
readList(io); |
| 2667 |
return; |
| 2668 |
} |
| 2669 |
else if(currToken == '[') |
| 2670 |
{ |
| 2671 |
readDimensionSet(io); |
| 2672 |
return; |
| 2673 |
} |
| 2674 |
else if(currToken == "uniform") |
| 2675 |
{ |
| 2676 |
if(!io.read(currToken)) |
| 2677 |
{ |
| 2678 |
throw vtkFoamError() |
| 2679 |
<< "Expected a uniform value or a list, found unexpected EOF"; |
| 2680 |
} |
| 2681 |
if(currToken == '(') |
| 2682 |
{ |
| 2683 |
readList(io); |
| 2684 |
} |
| 2685 |
else if(currToken.type() == vtkFoamToken::LABEL |
| 2686 |
|| currToken.type() == vtkFoamToken::SCALAR |
| 2687 |
|| currToken.type() == vtkFoamToken::STRING) |
| 2688 |
{ |
| 2689 |
vtkFoamToken::operator=(currToken); |
| 2690 |
} |
| 2691 |
else // unexpected punctuation token |
| 2692 |
{ |
| 2693 |
throw vtkFoamError() << "Expected number, string or (, found " |
| 2694 |
<< currToken; |
| 2695 |
} |
| 2696 |
isUniform_ = true; |
| 2697 |
} |
| 2698 |
else if(currToken == "nonuniform") |
| 2699 |
{ |
| 2700 |
if(!io.read(currToken)) |
| 2701 |
{ |
| 2702 |
throw vtkFoamError() << "Expected list type specifier, found EOF"; |
| 2703 |
} |
| 2704 |
isUniform_ = false; |
| 2705 |
if(currToken == "List<scalar>") |
| 2706 |
{ |
| 2707 |
readNonuniformList<SCALARLIST, listTraits<vtkFloatArray, float> >(io); |
| 2708 |
} |
| 2709 |
else if(currToken == "List<sphericalTensor>") |
| 2710 |
{ |
| 2711 |
readNonuniformList<VECTORLIST, |
| 2712 |
vectorListTraits<vtkFloatArray, float, 1, false> >(io); |
| 2713 |
} |
| 2714 |
else if(currToken == "List<vector>") |
| 2715 |
{ |
| 2716 |
readNonuniformList<VECTORLIST, |
| 2717 |
vectorListTraits<vtkFloatArray, float, 3, false> >(io); |
| 2718 |
} |
| 2719 |
else if(currToken == "List<symmTensor>") |
| 2720 |
{ |
| 2721 |
readNonuniformList<VECTORLIST, |
| 2722 |
vectorListTraits<vtkFloatArray, float, 6, false> >(io); |
| 2723 |
} |
| 2724 |
else if(currToken == "List<tensor>") |
| 2725 |
{ |
| 2726 |
readNonuniformList<VECTORLIST, |
| 2727 |
vectorListTraits<vtkFloatArray, float, 9, false> >(io); |
| 2728 |
} |
| 2729 |
// List<bool> is read as List<label> |
| 2730 |
else if(currToken =="List<label>" || currToken == "List<bool>") |
| 2731 |
{ |
| 2732 |
readNonuniformList<LABELLIST, listTraits<vtkIntArray, int> >(io); |
| 2733 |
} |
| 2734 |
// an empty list doesn't have a list type specifier |
| 2735 |
else if(currToken.type() == vtkFoamToken::LABEL |
| 2736 |
&& currToken.to<int>() == 0) |
| 2737 |
{ |
| 2738 |
type_ = EMPTYLIST; |
| 2739 |
io.readExpecting('('); |
| 2740 |
io.readExpecting(')'); |
| 2741 |
} |
| 2742 |
else |
| 2743 |
{ |
| 2744 |
throw vtkFoamError() << "Unsupported nonuniform list type " << currToken; |
| 2745 |
} |
| 2746 |
} |
| 2747 |
// zones have list without a uniform/nonuniform keyword |
| 2748 |
// List<bool> is read as List<label> |
| 2749 |
// (e. g. flipMap entry in faceZones) |
| 2750 |
else if(currToken == "List<label>" || currToken == "List<bool>") |
| 2751 |
{ |
| 2752 |
isUniform_ = false; |
| 2753 |
readNonuniformList<LABELLIST, listTraits<vtkIntArray, int> >(io); |
| 2754 |
} |
| 2755 |
else if(currToken.type() == vtkFoamToken::PUNCTUATION |
| 2756 |
|| currToken.type() == vtkFoamToken::LABEL |
| 2757 |
|| currToken.type() == vtkFoamToken::SCALAR |
| 2758 |
|| currToken.type() == vtkFoamToken::STRING |
| 2759 |
|| currToken.type() == vtkFoamToken::IDENTIFIER) |
| 2760 |
{ |
| 2761 |
vtkFoamToken::operator=(currToken); |
| 2762 |
} |
| 2763 |
} |
| 2764 |
|
| 2765 |
// read values of an entry |
| 2766 |
void vtkOpenFOAMReader::vtkFoamEntry::read(vtkFoamIOobject& io) |
| 2767 |
{ |
| 2768 |
for(;;) |
| 2769 |
{ |
| 2770 |
valuePtrs_.push_back(new vtkFoamEntryValue(this)); |
| 2771 |
valuePtrs_.back()->read(io); |
| 2772 |
|
| 2773 |
if(valuePtrs_.size() >= 2) |
| 2774 |
{ |
| 2775 |
vtkFoamEntryValue& secondLastValue |
| 2776 |
= *valuePtrs_[valuePtrs_.size() - 2]; |
| 2777 |
if(secondLastValue.type() == vtkFoamToken::LABEL) |
| 2778 |
{ |
| 2779 |
vtkFoamEntryValue& lastValue = *valuePtrs_.back(); |
| 2780 |
|
| 2781 |
// a zero-sized nonuniform list without prefixing "nonuniform" |
| 2782 |
// keyword nor list type specifier (i. e. `0()'; |
| 2783 |
// e. g. simpleEngine/0/polyMesh/pointZones) requires special |
| 2784 |
// care (one with nonuniform prefix is treated within |
| 2785 |
// vtkFoamEntryValue::read()). still this causes errornous |
| 2786 |
// behavior for `0 nonuniform 0()' but this should be extremely |
| 2787 |
// rare |
| 2788 |
if(lastValue.type() == vtkFoamToken::EMPTYLIST |
| 2789 |
&& secondLastValue == 0) |
| 2790 |
{ |
| 2791 |
delete valuePtrs_.back(); |
| 2792 |
valuePtrs_.pop_back(); // delete the last value |
| 2793 |
valuePtrs_.back()->setEmptyList(); // mark new last value as empty |
| 2794 |
} |
| 2795 |
// for an exceptional expression of `LABEL{LABELorSCALAR}' without |
| 2796 |
// type prefix (e. g. `2{-0}' in mixedRhoE B.C. in |
| 2797 |
// rhopSonicFoam/shockTube) |
| 2798 |
else if(lastValue.type() == vtkFoamToken::DICTIONARY) |
| 2799 |
{ |
| 2800 |
if(lastValue.dictionary().type() == vtkFoamToken::UNIFORMLABELLIST) |
| 2801 |
{ |
| 2802 |
const int size = secondLastValue.to<int>(); |
| 2803 |
const int value = lastValue.dictionary().to<int>(); |
| 2804 |
// delete last two values |
| 2805 |
delete valuePtrs_.back(); |
| 2806 |
valuePtrs_.pop_back(); |
| 2807 |
delete valuePtrs_.back(); |
| 2808 |
valuePtrs_.pop_back(); |
| 2809 |
// make new labelList |
| 2810 |
valuePtrs_.push_back(new vtkFoamEntryValue(this)); |
| 2811 |
valuePtrs_.back()->makeLabelList(value, size); |
| 2812 |
} |
| 2813 |
else if(lastValue.dictionary().type() |
| 2814 |
== vtkFoamToken::UNIFORMSCALARLIST) |
| 2815 |
{ |
| 2816 |
const int size = secondLastValue.to<int>(); |
| 2817 |
const float value = lastValue.dictionary().to<float>(); |
| 2818 |
// delete last two values |
| 2819 |
delete valuePtrs_.back(); |
| 2820 |
valuePtrs_.pop_back(); |
| 2821 |
delete valuePtrs_.back(); |
| 2822 |
valuePtrs_.pop_back(); |
| 2823 |
// make new labelList |
| 2824 |
valuePtrs_.push_back(new vtkFoamEntryValue(this)); |
| 2825 |
valuePtrs_.back()->makeScalarList(value, size); |
| 2826 |
} |
| 2827 |
} |
| 2828 |
} |
| 2829 |
} |
| 2830 |
|
| 2831 |
if(valuePtrs_.back()->type() == vtkFoamToken::IDENTIFIER) |
| 2832 |
{ |
| 2833 |
// substitute identifier |
| 2834 |
const vtkStdString identifier(valuePtrs_.back()->toIdentifier()); |
| 2835 |
delete valuePtrs_.back(); |
| 2836 |
valuePtrs_.pop_back(); |
| 2837 |
|
| 2838 |
for(vtkFoamDict *uDictPtr = upperDictPtr_;;) |
| 2839 |
{ |
| 2840 |
const vtkFoamEntry& identifiedEntry = uDictPtr->lookup(identifier); |
| 2841 |
|
| 2842 |
if(identifiedEntry.found()) |
| 2843 |
{ |
| 2844 |
for(size_t valueI = 0; valueI < identifiedEntry.size(); valueI++) |
| 2845 |
{ |
| 2846 |
valuePtrs_.push_back( |
| 2847 |
new vtkFoamEntryValue(identifiedEntry.value(valueI), this)); |
| 2848 |
} |
| 2849 |
break; |
| 2850 |
} |
| 2851 |
else |
| 2852 |
{ |
| 2853 |
uDictPtr = uDictPtr->upperDictPtr(); |
| 2854 |
if(uDictPtr == NULL) |
| 2855 |
{ |
| 2856 |
throw vtkFoamError() << "substituting entry " << identifier |
| 2857 |
<< " not found"; |
| 2858 |
} |
| 2859 |
} |
| 2860 |
} |
| 2861 |
} |
| 2862 |
else if(*valuePtrs_.back() == ';') |
| 2863 |
{ |
| 2864 |
delete valuePtrs_.back(); |
| 2865 |
valuePtrs_.pop_back(); |
| 2866 |
break; |
| 2867 |
} |
| 2868 |
else if(valuePtrs_.back()->type() == vtkFoamToken::DICTIONARY) |
| 2869 |
{ |
| 2870 |
// subdictionary is not suffixed by an entry terminator ';' |
| 2871 |
break; |
| 2872 |
} |
| 2873 |
else if(*valuePtrs_.back() == '}' || *valuePtrs_.back() == ')') |
| 2874 |
{ |
| 2875 |
throw vtkFoamError() << "Unmatched " << *valuePtrs_.back(); |
| 2876 |
} |
| 2877 |
} |
| 2878 |
} |
| 2879 |
|
| 2880 |
//----------------------------------------------------------------------------- |
| 2881 |
// constructor |
| 2882 |
vtkOpenFOAMReader::vtkOpenFOAMReader() |
| 2883 |
{ |
| 2884 |
vtkDebugMacro(<<"Constructor"); |
| 2885 |
this->SetNumberOfInputPorts(0); |
| 2886 |
|
| 2887 |
// INTIALIZE FILE NAME |
| 2888 |
this->FileName = NULL; |
| 2889 |
|
| 2890 |
// VTK CLASSES |
| 2891 |
this->PatchDataArraySelection = vtkDataArraySelection::New(); |
| 2892 |
this->CellDataArraySelection = vtkDataArraySelection::New(); |
| 2893 |
this->PointDataArraySelection = vtkDataArraySelection::New(); |
| 2894 |
this->LagrangianDataArraySelection = vtkDataArraySelection::New(); |
| 2895 |
|
| 2896 |
// Setup the Selection observer for the above selection arrays |
| 2897 |
this->SelectionObserver = vtkCallbackCommand::New(); |
| 2898 |
this->SelectionObserver |
| 2899 |
->SetCallback(&vtkOpenFOAMReader::SelectionModifiedCallback); |
| 2900 |
this->SelectionObserver->SetClientData(this); |
| 2901 |
|
| 2902 |
this->PatchDataArraySelection |
| 2903 |
->AddObserver(vtkCommand::ModifiedEvent,this->SelectionObserver); |
| 2904 |
this->CellDataArraySelection |
| 2905 |
->AddObserver(vtkCommand::ModifiedEvent,this->SelectionObserver); |
| 2906 |
this->PointDataArraySelection |
| 2907 |
->AddObserver(vtkCommand::ModifiedEvent,this->SelectionObserver); |
| 2908 |
this->LagrangianDataArraySelection |
| 2909 |
->AddObserver(vtkCommand::ModifiedEvent,this->SelectionObserver); |
| 2910 |
|
| 2911 |
// Initialise the Selection status arrays |
| 2912 |
this->CellSelectionOldStatus = 0xffffffff; |
| 2913 |
this->PointSelectionOldStatus = 0xffffffff; |
| 2914 |
this->LagrangianSelectionOldStatus = 0xffffffff; |
| 2915 |
this->PatchSelectionOldStatus = 0xffffffff; |
| 2916 |
this->CellSelectionStatus = 0; |
| 2917 |
this->PointSelectionStatus = 0; |
| 2918 |
this->LagrangianSelectionStatus = 0; |
| 2919 |
this->PatchSelectionStatus = 0; |
| 2920 |
|
| 2921 |
// DATA COUNTS |
| 2922 |
this->NumCells = 0; |
| 2923 |
this->NumPoints = 0; |
| 2924 |
|
| 2925 |
this->VolFieldFiles = vtkStringArray::New(); |
| 2926 |
this->PointFieldFiles = vtkStringArray::New(); |
| 2927 |
this->LagrangianPaths = vtkStringArray::New(); |
| 2928 |
this->LagrangianFieldFiles = vtkStringArray::New(); |
| 2929 |
this->OldFileName = new vtkStdString; |
| 2930 |
this->PathPrefix = new vtkStdString; |
| 2931 |
this->PolyMeshPointsDir = vtkStringArray::New(); |
| 2932 |
this->PolyMeshFacesDir = vtkStringArray::New(); |
| 2933 |
|
| 2934 |
// DATA TIMES |
| 2935 |
this->NumberOfTimeSteps = 0; |
| 2936 |
this->Steps = NULL; |
| 2937 |
this->TimeNames = vtkStringArray::New(); |
| 2938 |
this->TimeStep = 0; |
| 2939 |
this->TimeStepRange[0] = 0; |
| 2940 |
this->TimeStepRange[1] = 0; |
| 2941 |
|
| 2942 |
// for creating cell-to-point translated data |
| 2943 |
this->CreateCellToPoint = 1; |
| 2944 |
this->CreateCellToPointOld = 1; |
| 2945 |
this->BoundaryPointMap = NULL; |
| 2946 |
this->AllBoundaries = NULL; |
| 2947 |
this->AllBoundariesPointMap = NULL; |
| 2948 |
this->InternalPoints = NULL; |
| 2949 |
|
| 2950 |
// for caching mesh |
| 2951 |
this->CacheMesh = 1; |
| 2952 |
this->TimeStepOld = -1; |
| 2953 |
this->InternalMesh = NULL; |
| 2954 |
this->BoundaryMesh = NULL; |
| 2955 |
this->BoundaryDict = NULL; |
| 2956 |
this->BoundaryPointMap = NULL; |
| 2957 |
this->FaceOwner = NULL; |
| 2958 |
this->PointZoneMesh = NULL; |
| 2959 |
this->FaceZoneMesh = NULL; |
| 2960 |
this->CellZoneMesh = NULL; |
| 2961 |
|
| 2962 |
// for decomposing polyhedra |
| 2963 |
this->DecomposePolyhedra = 1; |
| 2964 |
this->DecomposePolyhedraOld = 1; |
| 2965 |
this->AdditionalCellIds = NULL; |
| 2966 |
this->AdditionalCellPoints = NULL; |
| 2967 |
|
| 2968 |
// for accumulating patches across time-steps (Turned on by default) |
| 2969 |
// As of now, only accumulation of patches is implemented |
| 2970 |
this->KeepPatches = 1; |
| 2971 |
this->KeepPatchesOld = 1; |
| 2972 |
|
| 2973 |
// for reading old binary lagrangian/positions format |
| 2974 |
this->PositionsIsIn13Format = 0; // turned off by default |
| 2975 |
this->PositionsIsIn13FormatOld = 0; |
| 2976 |
|
| 2977 |
// for reading zones |
| 2978 |
this->ReadZones = 0; // turned off by default |
| 2979 |
this->ReadZonesOld = 0; |
| 2980 |
|
| 2981 |
// determine if time directories are to be listed according to controlDict |
| 2982 |
this->ListTimeStepsByControlDict = 0; |
| 2983 |
this->ListTimeStepsByControlDictOld = 0; |
| 2984 |
|
| 2985 |
// add dimensions to array names |
| 2986 |
this->AddDimensionsToArrayNames = 0; |
| 2987 |
this->AddDimensionsToArrayNamesOld = 0; |
| 2988 |
} |
| 2989 |
|
| 2990 |
//----------------------------------------------------------------------------- |
| 2991 |
// destructor |
| 2992 |
vtkOpenFOAMReader::~vtkOpenFOAMReader() |
| 2993 |
{ |
| 2994 |
vtkDebugMacro(<<"DeConstructor"); |
| 2995 |
|
| 2996 |
// Delete the Observers before deleting the Selection Arrays !!! |
| 2997 |
this->PatchDataArraySelection->RemoveObserver(this->SelectionObserver); |
| 2998 |
this->CellDataArraySelection->RemoveObserver(this->SelectionObserver); |
| 2999 |
this->PointDataArraySelection->RemoveObserver(this->SelectionObserver); |
| 3000 |
this->LagrangianDataArraySelection->RemoveObserver(this->SelectionObserver); |
| 3001 |
|
| 3002 |
// Now delete the Selection Observer itself |
| 3003 |
this->SelectionObserver->Delete(); |
| 3004 |
|
| 3005 |
// Finally delete the Selection Arrays |
| 3006 |
this->PatchDataArraySelection->Delete(); |
| 3007 |
this->CellDataArraySelection->Delete(); |
| 3008 |
this->PointDataArraySelection->Delete(); |
| 3009 |
this->LagrangianDataArraySelection->Delete(); |
| 3010 |
|
| 3011 |
this->SetFileName(0); |
| 3012 |
delete this->OldFileName; |
| 3013 |
delete this->PathPrefix; |
| 3014 |
this->PolyMeshPointsDir->Delete(); |
| 3015 |
this->PolyMeshFacesDir->Delete(); |
| 3016 |
|
| 3017 |
delete [] this->Steps; |
| 3018 |
this->TimeNames->Delete(); |
| 3019 |
this->VolFieldFiles->Delete(); |
| 3020 |
this->PointFieldFiles->Delete(); |
| 3021 |
this->LagrangianPaths->Delete(); |
| 3022 |
this->LagrangianFieldFiles->Delete(); |
| 3023 |
|
| 3024 |
this->ClearMeshes(); |
| 3025 |
delete this->BoundaryDict; |
| 3026 |
} |
| 3027 |
|
| 3028 |
void vtkOpenFOAMReader::ClearInternalMeshes() |
| 3029 |
{ |
| 3030 |
if(this->FaceOwner != NULL) |
| 3031 |
{ |
| 3032 |
this->FaceOwner->Delete(); |
| 3033 |
this->FaceOwner = NULL; |
| 3034 |
} |
| 3035 |
if(this->InternalMesh != NULL) |
| 3036 |
{ |
| 3037 |
this->InternalMesh->Delete(); |
| 3038 |
this->InternalMesh = NULL; |
| 3039 |
} |
| 3040 |
if(this->AdditionalCellIds != NULL) |
| 3041 |
{ |
| 3042 |
this->AdditionalCellIds->Delete(); |
| 3043 |
this->AdditionalCellIds = NULL; |
| 3044 |
} |
| 3045 |
delete this->AdditionalCellPoints; |
| 3046 |
this->AdditionalCellPoints = NULL; |
| 3047 |
|
| 3048 |
delete this->PointZoneMesh; |
| 3049 |
this->PointZoneMesh = NULL; |
| 3050 |
delete this->FaceZoneMesh; |
| 3051 |
this->FaceZoneMesh = NULL; |
| 3052 |
delete this->CellZoneMesh; |
| 3053 |
this->CellZoneMesh = NULL; |
| 3054 |
} |
| 3055 |
|
| 3056 |
void vtkOpenFOAMReader::ClearBoundaryMeshes() |
| 3057 |
{ |
| 3058 |
delete this->BoundaryMesh; |
| 3059 |
this->BoundaryMesh = NULL; |
| 3060 |
|
| 3061 |
delete this->BoundaryPointMap; |
| 3062 |
this->BoundaryPointMap = NULL; |
| 3063 |
|
| 3064 |
if(this->InternalPoints != NULL) |
| 3065 |
{ |
| 3066 |
this->InternalPoints->Delete(); |
| 3067 |
this->InternalPoints = NULL; |
| 3068 |
} |
| 3069 |
if(this->AllBoundaries != NULL) |
| 3070 |
{ |
| 3071 |
this->AllBoundaries->Delete(); |
| 3072 |
this->AllBoundaries = NULL; |
| 3073 |
} |
| 3074 |
if(this->AllBoundariesPointMap != NULL) |
| 3075 |
{ |
| 3076 |
this->AllBoundariesPointMap->Delete(); |
| 3077 |
this->AllBoundariesPointMap = NULL; |
| 3078 |
} |
| 3079 |
} |
| 3080 |
|
| 3081 |
void vtkOpenFOAMReader::ClearMeshes() |
| 3082 |
{ |
| 3083 |
this->ClearInternalMeshes(); |
| 3084 |
this->ClearBoundaryMeshes(); |
| 3085 |
} |
| 3086 |
|
| 3087 |
//----------------------------------------------------------------------------- |
| 3088 |
// CanReadFile |
| 3089 |
int vtkOpenFOAMReader::CanReadFile(const char * /* fileName */) |
| 3090 |
{ |
| 3091 |
// so far CanReadFile does nothing. |
| 3092 |
return 1; |
| 3093 |
} |
| 3094 |
|
| 3095 |
//----------------------------------------------------------------------------- |
| 3096 |
// RequestInformation |
| 3097 |
int vtkOpenFOAMReader::RequestInformation( |
| 3098 |
vtkInformation *vtkNotUsed(request), |
| 3099 |
vtkInformationVector **vtkNotUsed(inputVector), |
| 3100 |
vtkInformationVector *outputVector) |
| 3101 |
{ |
| 3102 |
if(!this->FileName || strlen(this->FileName) == 0) |
| 3103 |
{ |
| 3104 |
vtkErrorMacro("FileName has to be specified!"); |
| 3105 |
return 0; |
| 3106 |
} |
| 3107 |
vtkDebugMacro(<<"Request Info: " <<this->FileName); |
| 3108 |
|
| 3109 |
if(*this->OldFileName != vtkStdString(this->FileName) |
| 3110 |
|| this->ListTimeStepsByControlDict != this->ListTimeStepsByControlDictOld) |
| 3111 |
{ |
| 3112 |
// updated this->OldFileName |
| 3113 |
*this->OldFileName = vtkStdString(this->FileName); |
| 3114 |
|
| 3115 |
// clear prior case information |
| 3116 |
this->TimeStepOld = -1; |
| 3117 |
delete [] this->Steps; |
| 3118 |
this->Steps = NULL; |
| 3119 |
|
| 3120 |
this->ClearMeshes(); |
| 3121 |
delete this->BoundaryDict; |
| 3122 |
this->BoundaryDict = NULL; |
| 3123 |
|
| 3124 |
this->CellDataArraySelection->RemoveAllArrays(); |
| 3125 |
this->PointDataArraySelection->RemoveAllArrays(); |
| 3126 |
this->LagrangianDataArraySelection->RemoveAllArrays(); |
| 3127 |
this->PatchDataArraySelection->RemoveAllArrays(); |
| 3128 |
|
| 3129 |
// make case information |
| 3130 |
if(!this->ReadControlDict(this->FileName)) |
| 3131 |
{ |
| 3132 |
return 0; |
| 3133 |
} |
| 3134 |
if(this->NumberOfTimeSteps == 0) |
| 3135 |
{ |
| 3136 |
vtkErrorMacro(<< this->FileName << " contains no timestep data."); |
| 3137 |
return 0; |
| 3138 |
} |
| 3139 |
this->TimeStepRange[0] = 0; |
| 3140 |
this->TimeStepRange[1] = this->NumberOfTimeSteps; |
| 3141 |
this->PopulatePolyMeshDirArrays(); |
| 3142 |
outputVector->GetInformationObject(0)->Set( |
| 3143 |
vtkStreamingDemandDrivenPipeline::TIME_STEPS(), this->Steps, |
| 3144 |
this->NumberOfTimeSteps); |
| 3145 |
#if PARAVIEW_VERSION_MAJOR >= 3 |
| 3146 |
double timeRange[2]; |
| 3147 |
timeRange[0] = this->Steps[0]; |
| 3148 |
timeRange[1] = this->Steps[this->NumberOfTimeSteps - 1]; |
| 3149 |
outputVector->GetInformationObject(0)->Set( |
| 3150 |
vtkStreamingDemandDrivenPipeline::TIME_RANGE(), timeRange, 2); |
| 3151 |
#endif |
| 3152 |
} |
| 3153 |
|
| 3154 |
return this->MakeTimeStepData(true); |
| 3155 |
} |
| 3156 |
|
| 3157 |
//----------------------------------------------------------------------------- |
| 3158 |
// RequestData |
| 3159 |
int vtkOpenFOAMReader::RequestData( |
| 3160 |
vtkInformation *vtkNotUsed(request), |
| 3161 |
vtkInformationVector **vtkNotUsed(inputVector), |
| 3162 |
vtkInformationVector *outputVector) |
| 3163 |
{ |
| 3164 |
vtkDebugMacro(<<"Request Data"); |
| 3165 |
vtkInformation* outInfo = outputVector->GetInformationObject(0); |
| 3166 |
vtkMultiBlockDataSet *output = vtkMultiBlockDataSet::SafeDownCast( |
| 3167 |
outInfo->Get(vtkDataObject::DATA_OBJECT())); |
| 3168 |
|
| 3169 |
if(!this->FileName) |
| 3170 |
{ |
| 3171 |
vtkErrorMacro("FileName has to be specified!"); |
| 3172 |
return 0; |
| 3173 |
} |
| 3174 |
|
| 3175 |
if(this->NumberOfTimeSteps == 0) |
| 3176 |
{ |
| 3177 |
vtkErrorMacro(<< this->FileName << " contains no timestep data."); |
| 3178 |
return 0; |
| 3179 |
} |
| 3180 |
|
| 3181 |
if(this->TimeStep < this->TimeStepRange[0] |
| 3182 |
|| this->TimeStep > this->TimeStepRange[1]) |
| 3183 |
{ |
| 3184 |
vtkErrorMacro("TimeStep out of range"); |
| 3185 |
return 0; |
| 3186 |
} |
| 3187 |
|
| 3188 |
#if PARAVIEW_VERSION_MAJOR >= 3 |
| 3189 |
if(outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEPS())) |
| 3190 |
{ |
| 3191 |
double* requestedTimeValues |
| 3192 |
= outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEPS()); |
| 3193 |
int nSteps |
| 3194 |
= outInfo->Length(vtkStreamingDemandDrivenPipeline::TIME_STEPS()); |
| 3195 |
double* steps |
| 3196 |
= outInfo->Get(vtkStreamingDemandDrivenPipeline::TIME_STEPS()); |
| 3197 |
#if 0 |
| 3198 |
int timeI = 0; |
| 3199 |
while(timeI < nSteps - 1 && steps[timeI] < requestedTimeValues[0]) |
| 3200 |
{ |
| 3201 |
timeI++; |
| 3202 |
} |
| 3203 |
this->TimeStep = timeI; |
| 3204 |
outInfo->Set(vtkDataObject::DATA_TIME_STEPS(), &steps[timeI], 1); |
| 3205 |
#else |
| 3206 |
int minTimeI = 0; |
| 3207 |
if(nSteps > 0) |
| 3208 |
{ |
| 3209 |
const double requestedTime = requestedTimeValues[0]; |
| 3210 |
double minTimeDiff = fabs(steps[0] - requestedTime); |
| 3211 |
for(int timeI = 1; timeI < nSteps; timeI++) |
| 3212 |
{ |
| 3213 |
const double timeDiff = fabs(steps[timeI] - requestedTime); |
| 3214 |
if(timeDiff < minTimeDiff) |
| 3215 |
{ |
| 3216 |
minTimeI = timeI; |
| 3217 |
minTimeDiff = timeDiff; |
| 3218 |
} |
| 3219 |
} |
| 3220 |
} |
| 3221 |
this->TimeStep = minTimeI; |
| 3222 |
outInfo->Set(vtkDataObject::DATA_TIME_STEPS(), &steps[minTimeI], 1); |
| 3223 |
#endif |
| 3224 |
} |
| 3225 |
#endif |
| 3226 |
|
| 3227 |
// find fields in this timestep |
| 3228 |
if(!this->MakeTimeStepData(false)) |
| 3229 |
{ |
| 3230 |
return 0; |
| 3231 |
} |
| 3232 |
|
| 3233 |
// create dataset |
| 3234 |
const int ret = this->CreateDataSet(output, this->TimeStep); |
| 3235 |
|
| 3236 |
if(ret == 0) |
| 3237 |
{ |
| 3238 |
return ret; |
| 3239 |
} |
| 3240 |
|
| 3241 |
// update selection status |
| 3242 |
this->CellSelectionOldStatus = this->CellSelectionStatus; |
| 3243 |
this->PointSelectionOldStatus = this->PointSelectionStatus; |
| 3244 |
this->LagrangianSelectionOldStatus = this->LagrangianSelectionStatus; |
| 3245 |
this->PatchSelectionOldStatus = this->PatchSelectionStatus; |
| 3246 |
this->CreateCellToPointOld = this->CreateCellToPoint; |
| 3247 |
this->DecomposePolyhedraOld = this->DecomposePolyhedra; |
| 3248 |
this->KeepPatchesOld = this->KeepPatches; |
| 3249 |
this->PositionsIsIn13FormatOld = this->PositionsIsIn13Format; |
| 3250 |
this->ReadZonesOld = this->ReadZones; |
| 3251 |
this->ListTimeStepsByControlDictOld = this->ListTimeStepsByControlDict; |
| 3252 |
this->AddDimensionsToArrayNamesOld = this->AddDimensionsToArrayNames; |
| 3253 |
|
| 3254 |
return ret; |
| 3255 |
} |
| 3256 |
|
| 3257 |
//----------------------------------------------------------------------------- |
| 3258 |
// PrintSelf |
| 3259 |
void vtkOpenFOAMReader::PrintSelf(ostream& os, vtkIndent indent) |
| 3260 |
{ |
| 3261 |
vtkDebugMacro(<<"Print Self"); |
| 3262 |
this->Superclass::PrintSelf(os,indent); |
| 3263 |
os << indent << "File Name: " |
| 3264 |
<< (this->FileName ? this->FileName : "(none)") << "\n"; |
| 3265 |
// os << indent << "Number Of Nodes: " << this->NumPoints << "\n"; |
| 3266 |
os << indent << "Number Of Cells: " << this->NumCells << "\n"; |
| 3267 |
os << indent << "Number of Time Steps: " << this->NumberOfTimeSteps << endl; |
| 3268 |
os << indent << "TimeStepRange: " |
| 3269 |
<< this->TimeStepRange[0] << " - " << this->TimeStepRange[1] |
| 3270 |
<< endl; |
| 3271 |
os << indent << "TimeStep: " << this->TimeStep << endl; |
| 3272 |
return; |
| 3273 |
} |
| 3274 |
|
| 3275 |
//----------------------------------------------------------------------------- |
| 3276 |
// cell selection list handlers |
| 3277 |
int vtkOpenFOAMReader::GetNumberOfCellArrays() |
| 3278 |
{ |
| 3279 |
return this->CellDataArraySelection->GetNumberOfArrays(); |
| 3280 |
} |
| 3281 |
|
| 3282 |
const char* vtkOpenFOAMReader::GetCellArrayName(int index) |
| 3283 |
{ |
| 3284 |
return this->CellDataArraySelection->GetArrayName(index); |
| 3285 |
} |
| 3286 |
|
| 3287 |
int vtkOpenFOAMReader::GetCellArrayStatus(const char* name) |
| 3288 |
{ |
| 3289 |
return this->CellDataArraySelection->ArrayIsEnabled(name); |
| 3290 |
} |
| 3291 |
|
| 3292 |
void vtkOpenFOAMReader::SetCellArrayStatus(const char* name, int status) |
| 3293 |
{ |
| 3294 |
if(status) |
| 3295 |
{ |
| 3296 |
this->CellDataArraySelection->EnableArray(name); |
| 3297 |
} |
| 3298 |
else |
| 3299 |
{ |
| 3300 |
this->CellDataArraySelection->DisableArray(name); |
| 3301 |
} |
| 3302 |
} |
| 3303 |
|
| 3304 |
void vtkOpenFOAMReader::DisableAllCellArrays() |
| 3305 |
{ |
| 3306 |
this->CellDataArraySelection->DisableAllArrays(); |
| 3307 |
} |
| 3308 |
|
| 3309 |
void vtkOpenFOAMReader::EnableAllCellArrays() |
| 3310 |
{ |
| 3311 |
this->CellDataArraySelection->EnableAllArrays(); |
| 3312 |
} |
| 3313 |
|
| 3314 |
//----------------------------------------------------------------------------- |
| 3315 |
// point selection list handlers |
| 3316 |
int vtkOpenFOAMReader::GetNumberOfPointArrays() |
| 3317 |
{ |
| 3318 |
return this->PointDataArraySelection->GetNumberOfArrays(); |
| 3319 |
} |
| 3320 |
|
| 3321 |
const char* vtkOpenFOAMReader::GetPointArrayName(int index) |
| 3322 |
{ |
| 3323 |
return this->PointDataArraySelection->GetArrayName(index); |
| 3324 |
} |
| 3325 |
|
| 3326 |
int vtkOpenFOAMReader::GetPointArrayStatus(const char* name) |
| 3327 |
{ |
| 3328 |
return this->PointDataArraySelection->ArrayIsEnabled(name); |
| 3329 |
} |
| 3330 |
|
| 3331 |
void vtkOpenFOAMReader::SetPointArrayStatus(const char* name, int status) |
| 3332 |
{ |
| 3333 |
if(status) |
| 3334 |
{ |
| 3335 |
this->PointDataArraySelection->EnableArray(name); |
| 3336 |
} |
| 3337 |
else |
| 3338 |
{ |
| 3339 |
this->PointDataArraySelection->DisableArray(name); |
| 3340 |
} |
| 3341 |
} |
| 3342 |
|
| 3343 |
void vtkOpenFOAMReader::DisableAllPointArrays() |
| 3344 |
{ |
| 3345 |
this->PointDataArraySelection->DisableAllArrays(); |
| 3346 |
} |
| 3347 |
|
| 3348 |
void vtkOpenFOAMReader::EnableAllPointArrays() |
| 3349 |
{ |
| 3350 |
this->PointDataArraySelection->EnableAllArrays(); |
| 3351 |
} |
| 3352 |
|
| 3353 |
|
| 3354 |
//----------------------------------------------------------------------------- |
| 3355 |
// lagrangian selection list handlers |
| 3356 |
int vtkOpenFOAMReader::GetNumberOfLagrangianArrays() |
| 3357 |
{ |
| 3358 |
return this->LagrangianDataArraySelection->GetNumberOfArrays(); |
| 3359 |
} |
| 3360 |
|
| 3361 |
const char* vtkOpenFOAMReader::GetLagrangianArrayName(int index) |
| 3362 |
{ |
| 3363 |
return this->LagrangianDataArraySelection->GetArrayName(index); |
| 3364 |
} |
| 3365 |
|
| 3366 |
int vtkOpenFOAMReader::GetLagrangianArrayStatus(const char* name) |
| 3367 |
{ |
| 3368 |
return this->LagrangianDataArraySelection->ArrayIsEnabled(name); |
| 3369 |
} |
| 3370 |
|
| 3371 |
void vtkOpenFOAMReader::SetLagrangianArrayStatus(const char* name, int status) |
| 3372 |
{ |
| 3373 |
if(status) |
| 3374 |
{ |
| 3375 |
this->LagrangianDataArraySelection->EnableArray(name); |
| 3376 |
} |
| 3377 |
else |
| 3378 |
{ |
| 3379 |
this->LagrangianDataArraySelection->DisableArray(name); |
| 3380 |
} |
| 3381 |
} |
| 3382 |
|
| 3383 |
void vtkOpenFOAMReader::DisableAllLagrangianArrays() |
| 3384 |
{ |
| 3385 |
this->LagrangianDataArraySelection->DisableAllArrays(); |
| 3386 |
} |
| 3387 |
|
| 3388 |
void vtkOpenFOAMReader::EnableAllLagrangianArrays() |
| 3389 |
{ |
| 3390 |
this->LagrangianDataArraySelection->EnableAllArrays(); |
| 3391 |
} |
| 3392 |
|
| 3393 |
|
| 3394 |
//----------------------------------------------------------------------------- |
| 3395 |
// patch selection list handlers |
| 3396 |
int vtkOpenFOAMReader::GetNumberOfPatchArrays() |
| 3397 |
{ |
| 3398 |
return this->PatchDataArraySelection->GetNumberOfArrays(); |
| 3399 |
} |
| 3400 |
|
| 3401 |
const char* vtkOpenFOAMReader::GetPatchArrayName(int index) |
| 3402 |
{ |
| 3403 |
return this->PatchDataArraySelection->GetArrayName(index); |
| 3404 |
} |
| 3405 |
|
| 3406 |
int vtkOpenFOAMReader::GetPatchArrayStatus(const char* name) |
| 3407 |
{ |
| 3408 |
return this->PatchDataArraySelection->ArrayIsEnabled(name); |
| 3409 |
} |
| 3410 |
|
| 3411 |
void vtkOpenFOAMReader::SetPatchArrayStatus(const char* name, int status) |
| 3412 |
{ |
| 3413 |
if(status) |
| 3414 |
{ |
| 3415 |
this->PatchDataArraySelection->EnableArray(name); |
| 3416 |
} |
| 3417 |
else |
| 3418 |
{ |
| 3419 |
this->PatchDataArraySelection->DisableArray(name); |
| 3420 |
} |
| 3421 |
} |
| 3422 |
|
| 3423 |
void vtkOpenFOAMReader::DisableAllPatchArrays() |
| 3424 |
{ |
| 3425 |
this->PatchDataArraySelection->DisableAllArrays(); |
| 3426 |
} |
| 3427 |
|
| 3428 |
void vtkOpenFOAMReader::EnableAllPatchArrays() |
| 3429 |
{ |
| 3430 |
this->PatchDataArraySelection->EnableAllArrays(); |
| 3431 |
} |
| 3432 |
|
| 3433 |
//----------------------------------------------------------------------------- |
| 3434 |
// selection observer |
| 3435 |
void vtkOpenFOAMReader::SelectionModifiedCallback(vtkObject*, |
| 3436 |
unsigned long, void* clientdata, void*) |
| 3437 |
{ |
| 3438 |
static_cast<vtkOpenFOAMReader*>(clientdata)->SelectionModified(true); |
| 3439 |
} |
| 3440 |
|
| 3441 |
unsigned long vtkOpenFOAMReader::CreateSelectionStatus( |
| 3442 |
vtkDataArraySelection *dataArraySelection, unsigned long selectionOldStatus) |
| 3443 |
{ |
| 3444 |
// Change the pipeline modification time to force update |
| 3445 |
// Update the selection status to detect changes |
| 3446 |
|
| 3447 |
// Cell Selection Arrays |
| 3448 |
// we loop from the last element of the selection array since we'd |
| 3449 |
// like to place newly added variables to extra higher bits (we |
| 3450 |
// wouldn't like to move the locations of already existing variables) |
| 3451 |
unsigned long selectionStatus = 0; |
| 3452 |
for(int i = dataArraySelection->GetNumberOfArrays() - 1; i >= 0; i--) |
| 3453 |
{ |
| 3454 |
selectionStatus = (selectionStatus << 1) |
| 3455 |
+ dataArraySelection->GetArraySetting(i); |
| 3456 |
} |
| 3457 |
// if the status flag overflows we'd like to fall onto the safe side |
| 3458 |
// (properly refresh the dataset without mesh caching) so we use the |
| 3459 |
// last bit (LSB) as overflow control flag. if overflow occurs the |
| 3460 |
// LSB is negated from the old status |
| 3461 |
if(dataArraySelection->GetNumberOfArrays() |
| 3462 |
<= static_cast<int>(sizeof(selectionStatus) * 8 - 1)) |
| 3463 |
{ |
| 3464 |
selectionStatus = (selectionStatus << 1) + (selectionOldStatus & 0x1); |
| 3465 |
} |
| 3466 |
else |
| 3467 |
{ |
| 3468 |
selectionStatus = (selectionStatus << 1) + ((~selectionOldStatus) & 0x1); |
| 3469 |
} |
| 3470 |
|
| 3471 |
return selectionStatus; |
| 3472 |
} |
| 3473 |
|
| 3474 |
void vtkOpenFOAMReader::SelectionModified(const bool setModified) |
| 3475 |
{ |
| 3476 |
this->CellSelectionStatus = this->CreateSelectionStatus( |
| 3477 |
this->CellDataArraySelection, this->CellSelectionOldStatus); |
| 3478 |
this->PointSelectionStatus = this->CreateSelectionStatus( |
| 3479 |
this->PointDataArraySelection, this->PointSelectionOldStatus); |
| 3480 |
this->LagrangianSelectionStatus = this->CreateSelectionStatus( |
| 3481 |
this->LagrangianDataArraySelection, this->LagrangianSelectionOldStatus); |
| 3482 |
this->PatchSelectionStatus = this->CreateSelectionStatus( |
| 3483 |
this->PatchDataArraySelection, this->PatchSelectionOldStatus); |
| 3484 |
|
| 3485 |
// Indicate that the pipeline needs to be updated (VTK Command) |
| 3486 |
if(setModified) |
| 3487 |
{ |
| 3488 |
this->Modified(); |
| 3489 |
} |
| 3490 |
} |
| 3491 |
|
| 3492 |
|
| 3493 |
//----------------------------------------------------------------------------- |
| 3494 |
void vtkOpenFOAMReader::GetFieldNames(const char *pathIn, |
| 3495 |
const bool isLagrangian, vtkStringArray *cellObjectNames, |
| 3496 |
vtkStringArray *pointObjectNames) |
| 3497 |
{ |
| 3498 |
const vtkStdString tempPath(pathIn); |
| 3499 |
|
| 3500 |
// open the directory and get num of files |
| 3501 |
vtkDirectory * directory = vtkDirectory::New(); |
| 3502 |
if(!directory->Open(tempPath.c_str())) |
| 3503 |
{ |
| 3504 |
// no data |
| 3505 |
directory->Delete(); |
| 3506 |
return; |
| 3507 |
} |
| 3508 |
|
| 3509 |
// loop over all files and locate valid fields |
| 3510 |
int nFieldFiles = directory->GetNumberOfFiles(); |
| 3511 |
for(int j = 0; j < nFieldFiles; j++) |
| 3512 |
{ |
| 3513 |
const vtkStdString fieldFile(directory->GetFile(j)); |
| 3514 |
const int len = fieldFile.length(); |
| 3515 |
|
| 3516 |
// excluded extensions cf. src/OpenFOAM/OSspecific/Unix/Unix.C |
| 3517 |
if(!directory->FileIsDirectory(fieldFile.c_str()) |
| 3518 |
&& fieldFile.substr(len - 1) != "~" |
| 3519 |
&& (len < 4 || (fieldFile.substr(len - 4) != ".bak" |
| 3520 |
&& fieldFile.substr(len - 4) != ".BAK" |
| 3521 |
&& fieldFile.substr(len - 4) != ".old")) |
| 3522 |
&& (len < 5 || fieldFile.substr(len - 5) != ".save")) |
| 3523 |
{ |
| 3524 |
vtkFoamIOobject io(*this->PathPrefix); |
| 3525 |
if(io.open(tempPath + "/" + fieldFile)) // file exists and readable |
| 3526 |
{ |
| 3527 |
const vtkStdString& cn = io.className(); |
| 3528 |
if(isLagrangian) |
| 3529 |
{ |
| 3530 |
if(cn == "scalarField" || cn == "vectorField" |
| 3531 |
|| cn == "sphericalTensorField" || cn == "symmTensorField" |
| 3532 |
|| cn == "tensorField") |
| 3533 |
{ |
| 3534 |
// real file name |
| 3535 |
this->LagrangianFieldFiles->InsertNextValue(fieldFile); |
| 3536 |
// object name |
| 3537 |
pointObjectNames->InsertNextValue(io.objectName()); |
| 3538 |
} |
| 3539 |
} |
| 3540 |
else |
| 3541 |
{ |
| 3542 |
if(cn == "volScalarField" || cn == "pointScalarField" |
| 3543 |
|| cn == "volVectorField" || cn == "pointVectorField" |
| 3544 |
|| cn == "volSphericalTensorField" |
| 3545 |
|| cn == "pointSphericalTensorField" |
| 3546 |
|| cn == "volSymmTensorField" || cn == "pointSymmTensorField" |
| 3547 |
|| cn == "volTensorField" || cn == "pointTensorField") |
| 3548 |
{ |
| 3549 |
if(cn.substr(0, 3) == "vol") |
| 3550 |
{ |
| 3551 |
// real file name |
| 3552 |
this->VolFieldFiles->InsertNextValue(fieldFile); |
| 3553 |
// object name |
| 3554 |
cellObjectNames->InsertNextValue(io.objectName()); |
| 3555 |
} |
| 3556 |
else |
| 3557 |
{ |
| 3558 |
this->PointFieldFiles->InsertNextValue(fieldFile); |
| 3559 |
pointObjectNames->InsertNextValue(io.objectName()); |
| 3560 |
} |
| 3561 |
} |
| 3562 |
} |
| 3563 |
io.close(); |
| 3564 |
} |
| 3565 |
} |
| 3566 |
} |
| 3567 |
pointObjectNames->Squeeze(); |
| 3568 |
if(isLagrangian) |
| 3569 |
{ |
| 3570 |
this->LagrangianFieldFiles->Squeeze(); |
| 3571 |
} |
| 3572 |
else |
| 3573 |
{ |
| 3574 |
this->VolFieldFiles->Squeeze(); |
| 3575 |
this->PointFieldFiles->Squeeze(); |
| 3576 |
cellObjectNames->Squeeze(); |
| 3577 |
} |
| 3578 |
directory->Delete(); |
| 3579 |
} |
| 3580 |
|
| 3581 |
//----------------------------------------------------------------------------- |
| 3582 |
// locate laglangian clouds |
| 3583 |
void vtkOpenFOAMReader::LocateLagrangianClouds( |
| 3584 |
vtkStringArray *lagrangianObjectNames, const vtkStdString &tempPath) |
| 3585 |
{ |
| 3586 |
vtkDirectory *directory = vtkDirectory::New(); |
| 3587 |
if(directory->Open((tempPath + "/lagrangian").c_str())) |
| 3588 |
{ |
| 3589 |
// search for sub-clouds (OF 1.5 format) |
| 3590 |
const int nFiles = directory->GetNumberOfFiles(); |
| 3591 |
bool isSubCloud = false; |
| 3592 |
for(int fileI = 0; fileI < nFiles; fileI++) |
| 3593 |
{ |
| 3594 |
const vtkStdString fileNameI(directory->GetFile(fileI)); |
| 3595 |
const vtkStdString subCloudPath(vtkStdString("lagrangian/") + fileNameI); |
| 3596 |
if(fileNameI != "." && fileNameI != ".." |
| 3597 |
&& directory->FileIsDirectory(fileNameI.c_str())) |
| 3598 |
{ |
| 3599 |
vtkFoamIOobject io(*this->PathPrefix); |
| 3600 |
if(io.open(tempPath + "/" + subCloudPath + "/positions") |
| 3601 |
&& io.className().find("Cloud") != vtkStdString::npos |
| 3602 |
&& io.objectName() == "positions") |
| 3603 |
{ |
| 3604 |
isSubCloud = true; |
| 3605 |
if(this->LagrangianPaths->LookupValue(subCloudPath) == -1) |
| 3606 |
{ |
| 3607 |
this->LagrangianPaths->InsertNextValue(subCloudPath.c_str()); |
| 3608 |
} |
| 3609 |
this->GetFieldNames((tempPath + "/" + subCloudPath).c_str(), true, |
| 3610 |
NULL, lagrangianObjectNames); |
| 3611 |
this->PatchDataArraySelection->AddArray(subCloudPath.c_str()); |
| 3612 |
} |
| 3613 |
} |
| 3614 |
} |
| 3615 |
// if there's no sub-cloud then OF < 1.5 format |
| 3616 |
if(!isSubCloud) |
| 3617 |
{ |
| 3618 |
vtkFoamIOobject io(*this->PathPrefix); |
| 3619 |
if(io.open(tempPath + "/lagrangian/positions") |
| 3620 |
&& io.className() == "Cloud" && io.objectName() == "positions") |
| 3621 |
{ |
| 3622 |
if(this->LagrangianPaths->LookupValue("lagrangian") == -1) |
| 3623 |
{ |
| 3624 |
this->LagrangianPaths->InsertNextValue("lagrangian"); |
| 3625 |
} |
| 3626 |
this->GetFieldNames((tempPath + "/lagrangian").c_str(), true, NULL, |
| 3627 |
lagrangianObjectNames); |
| 3628 |
this->PatchDataArraySelection->AddArray("lagrangian"); |
| 3629 |
} |
| 3630 |
} |
| 3631 |
this->LagrangianPaths->Squeeze(); |
| 3632 |
} |
| 3633 |
directory->Delete(); |
| 3634 |
} |
| 3635 |
|
| 3636 |
//----------------------------------------------------------------------------- |
| 3637 |
// create field data lists and cell/point array selection lists |
| 3638 |
int vtkOpenFOAMReader::MakeTimeStepData(const bool listNextTimeStep) |
| 3639 |
{ |
| 3640 |
// Read the patches from the boundary file into selection array |
| 3641 |
int timeState = this->TimeStep; |
| 3642 |
|
| 3643 |
if(this->BoundaryDict == NULL |
| 3644 |
|| this->PolyMeshFacesDir->GetValue(timeState) != this->BoundaryDict->timeDir |
| 3645 |
|| this->PatchSelectionStatus != this->PatchSelectionOldStatus) |
| 3646 |
{ |
| 3647 |
delete this->BoundaryDict; |
| 3648 |
vtkFoamDict *boundaryDict = this->GatherBlocks("polyMesh/boundary", |
| 3649 |
timeState, true); |
| 3650 |
if(boundaryDict == NULL) |
| 3651 |
{ |
| 3652 |
return 0; |
| 3653 |
} |
| 3654 |
this->BoundaryDict = new vtkFoamBoundaryDict; |
| 3655 |
this->BoundaryDict->timeDir = this->PolyMeshFacesDir->GetValue(timeState); |
| 3656 |
|
| 3657 |
// Add the internal mesh by default always |
| 3658 |
this->PatchDataArraySelection->AddArray("Internal Mesh"); |
| 3659 |
|
| 3660 |
// iterate through each entry in the boundary file |
| 3661 |
vtkFoamDict& boundaryDictRef = *boundaryDict; |
| 3662 |
int allBoundariesNextStartFace = 0; |
| 3663 |
for(size_t i = 0; i < boundaryDictRef.size(); i++) |
| 3664 |
{ |
| 3665 |
vtkFoamEntry& boundaryEntryI = boundaryDictRef.entry(i); |
| 3666 |
vtkFoamEntry& nFacesEntry = boundaryEntryI.dictionary().lookup("nFaces"); |
| 3667 |
if(!nFacesEntry.found()) |
| 3668 |
{ |
| 3669 |
vtkErrorMacro(<< "nFaces entry not found in boundary entry " |
| 3670 |
<< boundaryEntryI.keyword().c_str()); |
| 3671 |
return 0; |
| 3672 |
} |
| 3673 |
const int nFaces = nFacesEntry.toInt(); |
| 3674 |
|
| 3675 |
// extract name of the current patch for insertion |
| 3676 |
const vtkStdString& boundaryNameI = boundaryEntryI.keyword(); |
| 3677 |
|
| 3678 |
// create BoundaryDict entry |
| 3679 |
this->BoundaryDict->push_back(vtkFoamBoundaryEntry()); |
| 3680 |
vtkFoamBoundaryEntry& BoundaryDictRef = this->BoundaryDict->back(); |
| 3681 |
BoundaryDictRef.nFaces = nFaces; |
| 3682 |
BoundaryDictRef.boundaryName = boundaryNameI; |
| 3683 |
vtkFoamEntry& startFaceEntry |
| 3684 |
= boundaryEntryI.dictionary().lookup("startFace"); |
| 3685 |
if(!startFaceEntry.found()) |
| 3686 |
{ |
| 3687 |
vtkErrorMacro(<< "startFace entry not found in boundary entry " |
| 3688 |
<< boundaryEntryI.keyword().c_str()); |
| 3689 |
return 0; |
| 3690 |
} |
| 3691 |
|
| 3692 |
BoundaryDictRef.startFace = startFaceEntry.toInt(); |
| 3693 |
vtkFoamEntry& typeEntry = boundaryEntryI.dictionary().lookup("type"); |
| 3694 |
if(!typeEntry.found()) |
| 3695 |
{ |
| 3696 |
vtkErrorMacro(<< "type entry not found in boundary entry " |
| 3697 |
<< boundaryEntryI.keyword().c_str()); |
| 3698 |
return 0; |
| 3699 |
} |
| 3700 |
const vtkStdString& typeNameI = typeEntry.toString(); |
| 3701 |
BoundaryDictRef.isPhysicalBoundary |
| 3702 |
= (typeNameI == "patch" || typeNameI == "wall"); |
| 3703 |
BoundaryDictRef.allBoundariesStartFace = allBoundariesNextStartFace; |
| 3704 |
if(BoundaryDictRef.isPhysicalBoundary) |
| 3705 |
{ |
| 3706 |
allBoundariesNextStartFace += nFaces; |
| 3707 |
} |
| 3708 |
BoundaryDictRef.isActive = false; |
| 3709 |
// If the size of patch becomes zero, but KeepPatches is selected, |
| 3710 |
// do not remove from list, else, remove patch from list |
| 3711 |
if(this->PatchDataArraySelection->ArrayExists(boundaryNameI.c_str())) |
| 3712 |
{ |
| 3713 |
if(nFaces <= 0 && !this->KeepPatches) |
| 3714 |
{ |
| 3715 |
this->PatchDataArraySelection |
| 3716 |
->RemoveArrayByName(boundaryNameI.c_str()); |
| 3717 |
} |
| 3718 |
// Mark boundary if selected for display |
| 3719 |
else if(this->GetPatchArrayStatus(boundaryNameI.c_str())) |
| 3720 |
{ |
| 3721 |
BoundaryDictRef.isActive = true; |
| 3722 |
} |
| 3723 |
} |
| 3724 |
// the patch is added to list even if its size is zero, if |
| 3725 |
// KeepPatches is set to true |
| 3726 |
else |
| 3727 |
{ |
| 3728 |
this->PatchDataArraySelection->AddArray(boundaryNameI.c_str()); |
| 3729 |
// patch selections are off by default |
| 3730 |
this->PatchDataArraySelection->DisableArray(boundaryNameI.c_str()); |
| 3731 |
} |
| 3732 |
} |
| 3733 |
|
| 3734 |
delete boundaryDict; |
| 3735 |
} |
| 3736 |
|
| 3737 |
// Add scalars and vectors to metadata |
| 3738 |
vtkStdString tempPath |
| 3739 |
= *this->PathPrefix + this->TimeNames->GetValue(this->TimeStep); |
| 3740 |
// do not do "RemoveAllArrays()" to accumulate array selections |
| 3741 |
// this->CellDataArraySelection->RemoveAllArrays(); |
| 3742 |
this->VolFieldFiles->Initialize(); |
| 3743 |
this->PointFieldFiles->Initialize(); |
| 3744 |
vtkStringArray *cellObjectNames = vtkStringArray::New(); |
| 3745 |
vtkStringArray *pointObjectNames = vtkStringArray::New(); |
| 3746 |
this->GetFieldNames(tempPath.c_str(), false, cellObjectNames, |
| 3747 |
pointObjectNames); |
| 3748 |
|
| 3749 |
vtkStringArray *lagrangianObjectNames = vtkStringArray::New(); |
| 3750 |
this->LagrangianFieldFiles->Initialize(); |
| 3751 |
if(listNextTimeStep) |
| 3752 |
{ |
| 3753 |
this->LagrangianPaths->Initialize(); |
| 3754 |
} |
| 3755 |
this->LocateLagrangianClouds(lagrangianObjectNames, tempPath); |
| 3756 |
|
| 3757 |
// if the requested timestep is 0 then we also look at the next |
| 3758 |
// timestep to add extra objects that don't exist at timestep 0 into |
| 3759 |
// selection lists. Note the ObjectNames array will be recreated in |
| 3760 |
// RequestData() so we don't have to worry about duplicated fields. |
| 3761 |
if(listNextTimeStep && this->NumberOfTimeSteps >= 2 && this->TimeStep == 0) |
| 3762 |
{ |
| 3763 |
const vtkStdString tempPath |
| 3764 |
= *this->PathPrefix + this->TimeNames->GetValue(1); |
| 3765 |
this->GetFieldNames(tempPath.c_str(), false, cellObjectNames, |
| 3766 |
pointObjectNames); |
| 3767 |
// if lagrangian clouds were not found at timestep 0 |
| 3768 |
if(this->LagrangianPaths->GetNumberOfTuples() == 0) |
| 3769 |
{ |
| 3770 |
this->LocateLagrangianClouds(lagrangianObjectNames, tempPath); |
| 3771 |
} |
| 3772 |
} |
| 3773 |
|
| 3774 |
#if PARAVIEW_VERSION_MAJOR >= 3 |
| 3775 |
// sort array names |
| 3776 |
vtkSortDataArray::Sort(cellObjectNames, this->VolFieldFiles); |
| 3777 |
#endif |
| 3778 |
for(int nameI = 0; nameI < cellObjectNames->GetNumberOfValues(); nameI++) |
| 3779 |
{ |
| 3780 |
this->CellDataArraySelection |
| 3781 |
->AddArray(cellObjectNames->GetValue(nameI).c_str()); |
| 3782 |
} |
| 3783 |
cellObjectNames->Delete(); |
| 3784 |
#if PARAVIEW_VERSION_MAJOR >= 3 |
| 3785 |
vtkSortDataArray::Sort(pointObjectNames, this->PointFieldFiles); |
| 3786 |
#endif |
| 3787 |
for(int nameI = 0; nameI < pointObjectNames->GetNumberOfValues(); nameI++) |
| 3788 |
{ |
| 3789 |
this->PointDataArraySelection |
| 3790 |
->AddArray(pointObjectNames->GetValue(nameI).c_str()); |
| 3791 |
} |
| 3792 |
pointObjectNames->Delete(); |
| 3793 |
#if PARAVIEW_VERSION_MAJOR >= 3 |
| 3794 |
vtkSortDataArray::Sort(lagrangianObjectNames, this->LagrangianFieldFiles); |
| 3795 |
#endif |
| 3796 |
for(int nameI = 0; nameI < lagrangianObjectNames->GetNumberOfValues(); |
| 3797 |
nameI++) |
| 3798 |
{ |
| 3799 |
this->LagrangianDataArraySelection |
| 3800 |
->AddArray(lagrangianObjectNames->GetValue(nameI).c_str()); |
| 3801 |
} |
| 3802 |
lagrangianObjectNames->Delete(); |
| 3803 |
|
| 3804 |
// refresh selection status: should not change the Modified status |
| 3805 |
// when called from RequestInformation() nor RequestData(). |
| 3806 |
this->SelectionModified(false); |
| 3807 |
return 1; |
| 3808 |
} |
| 3809 |
|
| 3810 |
//----------------------------------------------------------------------------- |
| 3811 |
// list time directories according to controlDict |
| 3812 |
bool vtkOpenFOAMReader::ListTimeDirectoriesByControlDict(vtkFoamDict* dictPtr) |
| 3813 |
{ |
| 3814 |
vtkFoamDict& dict = *dictPtr; |
| 3815 |
|
| 3816 |
vtkFoamEntry& startTimeEntry = dict.lookup("startTime"); |
| 3817 |
if(!startTimeEntry.found()) |
| 3818 |
{ |
| 3819 |
vtkErrorMacro(<< "startTime entry not found in controlDict"); |
| 3820 |
return false; |
| 3821 |
} |
| 3822 |
// using double to precisely handle time values |
| 3823 |
const double startTime = startTimeEntry.toDouble(); |
| 3824 |
|
| 3825 |
vtkFoamEntry& endTimeEntry = dict.lookup("endTime"); |
| 3826 |
if(!endTimeEntry.found()) |
| 3827 |
{ |
| 3828 |
vtkErrorMacro(<< "endTime entry not found in controlDict"); |
| 3829 |
return false; |
| 3830 |
} |
| 3831 |
const double endTime = endTimeEntry.toDouble(); |
| 3832 |
|
| 3833 |
vtkFoamEntry& deltaTEntry = dict.lookup("deltaT"); |
| 3834 |
if(!deltaTEntry.found()) |
| 3835 |
{ |
| 3836 |
vtkErrorMacro(<< "deltaT entry not found in controlDict"); |
| 3837 |
return false; |
| 3838 |
} |
| 3839 |
const double deltaT = deltaTEntry.toDouble(); |
| 3840 |
|
| 3841 |
vtkFoamEntry& writeIntervalEntry = dict.lookup("writeInterval"); |
| 3842 |
if(!writeIntervalEntry.found()) |
| 3843 |
{ |
| 3844 |
vtkErrorMacro(<< "writeInterval entry not found in controlDict"); |
| 3845 |
return false; |
| 3846 |
} |
| 3847 |
const double writeInterval = writeIntervalEntry.toDouble(); |
| 3848 |
|
| 3849 |
vtkFoamEntry& timeFormatEntry = dict.lookup("timeFormat"); |
| 3850 |
if(!timeFormatEntry.found()) |
| 3851 |
{ |
| 3852 |
vtkErrorMacro(<< "timeFormat entry not found in controlDict"); |
| 3853 |
return false; |
| 3854 |
} |
| 3855 |
const vtkStdString timeFormat(timeFormatEntry.toString()); |
| 3856 |
|
| 3857 |
vtkFoamEntry& timePrecisionEntry = dict.lookup("timePrecision"); |
| 3858 |
const int timePrecision // default is 6 |
| 3859 |
= (timePrecisionEntry.found() ? timePrecisionEntry.toInt() : 6); |
| 3860 |
|
| 3861 |
// calculate the time step increment based on type of run |
| 3862 |
const vtkStdString writeControl(dict.lookup("writeControl").toString()); |
| 3863 |
double timeStepIncrement; |
| 3864 |
if(writeControl == "timeStep") |
| 3865 |
{ |
| 3866 |
vtkDebugMacro(<<"Time step type data"); |
| 3867 |
timeStepIncrement = writeInterval * deltaT; |
| 3868 |
} |
| 3869 |
else if(writeControl == "runTime" || writeControl == "adjustableRunTime") |
| 3870 |
{ |
| 3871 |
vtkDebugMacro(<<"Run time type data"); |
| 3872 |
timeStepIncrement = writeInterval; |
| 3873 |
} |
| 3874 |
else |
| 3875 |
{ |
| 3876 |
vtkErrorMacro(<<"Time step can't be determined because writeControl is" |
| 3877 |
" set to " << writeControl.c_str()); |
| 3878 |
return false; |
| 3879 |
} |
| 3880 |
|
| 3881 |
// calculate how many timesteps there should be |
| 3882 |
const double tempResult = (endTime - startTime) / timeStepIncrement; |
| 3883 |
// +0.5 to round up |
| 3884 |
const int tempNumTimeSteps = static_cast<int>(tempResult + 0.5) + 1; |
| 3885 |
|
| 3886 |
// make sure time step dir exists |
| 3887 |
vtkstd::vector<double> tempSteps; |
| 3888 |
vtkDirectory *test = vtkDirectory::New(); |
| 3889 |
this->TimeNames->Initialize(); |
| 3890 |
|
| 3891 |
// determine time name based on Foam::Time::timeName() |
| 3892 |
// cf. src/OpenFOAM/db/Time/Time.C |
| 3893 |
vtksys_ios::ostringstream parser; |
| 3894 |
#ifdef _MSC_VER |
| 3895 |
bool correctExponent = true; |
| 3896 |
#endif |
| 3897 |
if(timeFormat == "general") |
| 3898 |
{ |
| 3899 |
// "do not use std:: or vtkstd:: when using anything declared in |
| 3900 |
// iostream," according to VTK coding standards, but following |
| 3901 |
// the instruction causes errors... |
| 3902 |
parser.setf(vtkstd::ios_base::fmtflags(0), vtkstd::ios_base::floatfield); |
| 3903 |
} |
| 3904 |
else if(timeFormat == "fixed") |
| 3905 |
{ |
| 3906 |
parser.setf(vtkstd::ios_base::fmtflags(vtkstd::ios_base::fixed), |
| 3907 |
vtkstd::ios_base::floatfield); |
| 3908 |
#ifdef _MSC_VER |
| 3909 |
correctExponent = false; |
| 3910 |
#endif |
| 3911 |
} |
| 3912 |
else if(timeFormat == "scientific") |
| 3913 |
{ |
| 3914 |
parser.setf(vtkstd::ios_base::fmtflags(vtkstd::ios_base::scientific), |
| 3915 |
vtkstd::ios_base::floatfield); |
| 3916 |
} |
| 3917 |
else |
| 3918 |
{ |
| 3919 |
vtkWarningMacro("Warning: unsupported time format. Assuming general."); |
| 3920 |
parser.setf(vtkstd::ios_base::fmtflags(0), vtkstd::ios_base::floatfield); |
| 3921 |
} |
| 3922 |
parser.precision(timePrecision); |
| 3923 |
|
| 3924 |
for(int i = 0; i < tempNumTimeSteps; i++) |
| 3925 |
{ |
| 3926 |
parser.str(""); |
| 3927 |
const double tempStep = i * timeStepIncrement + startTime; |
| 3928 |
parser << tempStep; // stringstream doesn't require ends |
| 3929 |
#ifdef _MSC_VER |
| 3930 |
// workaround for format difference in MSVC++: |
| 3931 |
// remove an extra 0 from exponent |
| 3932 |
if(correctExponent) |
| 3933 |
{ |
| 3934 |
vtkStdString tempStr(parser.str()); |
| 3935 |
size_t pos = tempStr.find('e'); |
| 3936 |
if(pos != vtkStdString::npos && tempStr.length() >= pos + 3 |
| 3937 |
&& tempStr[pos + 2] == '0') |
| 3938 |
{ |
| 3939 |
tempStr.erase(pos + 2, 1); |
| 3940 |
parser.str(tempStr); |
| 3941 |
} |
| 3942 |
} |
| 3943 |
#endif |
| 3944 |
if(test->Open((*this->PathPrefix + parser.str()).c_str())) |
| 3945 |
{ |
| 3946 |
tempSteps.push_back(tempStep); |
| 3947 |
this->TimeNames->InsertNextValue(parser.str()); |
| 3948 |
} |
| 3949 |
// necessary for reading the case/0 directory whatever the timeFormat is |
| 3950 |
// based on Foam::Time::operator++() cf. src/OpenFOAM/db/Time/Time.C |
| 3951 |
else if((fabs(tempStep) < 1.0e-14L) // 10*SMALL |
| 3952 |
&& test->Open((*this->PathPrefix + vtkStdString("0")).c_str())) |
| 3953 |
{ |
| 3954 |
tempSteps.push_back(tempStep); |
| 3955 |
this->TimeNames->InsertNextValue(vtkStdString("0")); |
| 3956 |
} |
| 3957 |
} |
| 3958 |
test->Delete(); |
| 3959 |
this->TimeNames->Squeeze(); |
| 3960 |
|
| 3961 |
// Add the time steps that actually exist to steps |
| 3962 |
// allows the run to be stopped short of controlDict spec |
| 3963 |
// allows for removal of timesteps |
| 3964 |
this->NumberOfTimeSteps = tempSteps.size(); |
| 3965 |
if(this->NumberOfTimeSteps > 0) |
| 3966 |
{ |
| 3967 |
this->Steps = new double[this->NumberOfTimeSteps]; |
| 3968 |
for(int i = 0; i < this->NumberOfTimeSteps; i++) |
| 3969 |
{ |
| 3970 |
this->Steps[i] = tempSteps[i]; |
| 3971 |
} |
| 3972 |
} |
| 3973 |
else |
| 3974 |
{ |
| 3975 |
// dummy for safely deleting later |
| 3976 |
this->Steps = new double[1]; |
| 3977 |
this->Steps[0] = startTime; |
| 3978 |
|
| 3979 |
// set the number of timesteps to 1 if the constant subdirectory exists |
| 3980 |
test = vtkDirectory::New(); |
| 3981 |
if(test->Open((*this->PathPrefix + "constant").c_str())) |
| 3982 |
{ |
| 3983 |
parser.str(""); |
| 3984 |
parser << startTime; |
| 3985 |
this->TimeNames->InsertNextValue(parser.str()); |
| 3986 |
this->TimeNames->Squeeze(); |
| 3987 |
this->NumberOfTimeSteps = 1; |
| 3988 |
} |
| 3989 |
test->Delete(); |
| 3990 |
} |
| 3991 |
return true; |
| 3992 |
} |
| 3993 |
|
| 3994 |
//----------------------------------------------------------------------------- |
| 3995 |
// list time directories by searching all valid time instances in a |
| 3996 |
// case directory |
| 3997 |
bool vtkOpenFOAMReader::ListTimeDirectoriesByInstances() |
| 3998 |
{ |
| 3999 |
// open the case directory |
| 4000 |
vtkDirectory* test = vtkDirectory::New(); |
| 4001 |
if(!test->Open(this->PathPrefix->c_str())) |
| 4002 |
{ |
| 4003 |
test->Delete(); |
| 4004 |
vtkErrorMacro(<< "Can't open directory " << this->PathPrefix->c_str()); |
| 4005 |
return false; |
| 4006 |
} |
| 4007 |
|
| 4008 |
// search all the directories in the case directory and detect |
| 4009 |
// directories with names convertible to numbers |
| 4010 |
this->TimeNames->Initialize(); |
| 4011 |
vtkDoubleArray* timeValues = vtkDoubleArray::New(); |
| 4012 |
const int nFiles = test->GetNumberOfFiles(); |
| 4013 |
for(int i = 0; i < nFiles; i++) |
| 4014 |
{ |
| 4015 |
const vtkStdString dir = test->GetFile(i); |
| 4016 |
if(test->FileIsDirectory(dir.c_str())) |
| 4017 |
{ |
| 4018 |
// check if the name is convertible to a number |
| 4019 |
bool isTimeDir = true; |
| 4020 |
for(size_t j = 0; j < dir.length(); j++) |
| 4021 |
{ |
| 4022 |
const char c = dir[j]; |
| 4023 |
if(!isdigit(c) && c != '+' && c != '-' && c != '.' && c != 'e' |
| 4024 |
&& c != 'E') |
| 4025 |
{ |
| 4026 |
isTimeDir = false; |
| 4027 |
break; |
| 4028 |
} |
| 4029 |
} |
| 4030 |
if(!isTimeDir) |
| 4031 |
{ |
| 4032 |
continue; |
| 4033 |
} |
| 4034 |
|
| 4035 |
// convert to a number |
| 4036 |
char *endptr; |
| 4037 |
double timeValue = strtod(dir.c_str(), &endptr); |
| 4038 |
// check if the value really was converted to a number |
| 4039 |
if(timeValue == 0.0 && endptr == dir.c_str()) |
| 4040 |
{ |
| 4041 |
continue; |
| 4042 |
} |
| 4043 |
|
| 4044 |
// add to the instance list |
| 4045 |
timeValues->InsertNextValue(timeValue); |
| 4046 |
this->TimeNames->InsertNextValue(dir); |
| 4047 |
} |
| 4048 |
} |
| 4049 |
test->Delete(); |
| 4050 |
timeValues->Squeeze(); |
| 4051 |
this->TimeNames->Squeeze(); |
| 4052 |
|
| 4053 |
// sort the detected time directories and set as timesteps |
| 4054 |
this->NumberOfTimeSteps = this->TimeNames->GetSize(); |
| 4055 |
if(this->NumberOfTimeSteps > 0) |
| 4056 |
{ |
| 4057 |
if(this->NumberOfTimeSteps > 1) |
| 4058 |
{ |
| 4059 |
vtkSortDataArray::Sort(timeValues, this->TimeNames); |
| 4060 |
} |
| 4061 |
this->Steps = new double[this->NumberOfTimeSteps]; |
| 4062 |
for(int i = 0; i < this->NumberOfTimeSteps; i++) |
| 4063 |
{ |
| 4064 |
this->Steps[i] = timeValues->GetValue(i); |
| 4065 |
} |
| 4066 |
} |
| 4067 |
else |
| 4068 |
{ |
| 4069 |
// dummy for safely deleting later |
| 4070 |
this->Steps = new double[1]; |
| 4071 |
this->Steps[0] = 0.0; |
| 4072 |
|
| 4073 |
// set the number of timesteps to 1 if the constant subdirectory exists |
| 4074 |
test = vtkDirectory::New(); |
| 4075 |
if(test->Open((*this->PathPrefix + "constant").c_str())) |
| 4076 |
{ |
| 4077 |
this->TimeNames->InsertNextValue("0"); |
| 4078 |
this->TimeNames->Squeeze(); |
| 4079 |
this->NumberOfTimeSteps = 1; |
| 4080 |
} |
| 4081 |
test->Delete(); |
| 4082 |
} |
| 4083 |
timeValues->Delete(); |
| 4084 |
|
| 4085 |
return true; |
| 4086 |
} |
| 4087 |
|
| 4088 |
//----------------------------------------------------------------------------- |
| 4089 |
// reads the controlDict file |
| 4090 |
// gather the necessary information to create a path to the data |
| 4091 |
bool vtkOpenFOAMReader::ReadControlDict(const char* pathIn) |
| 4092 |
{ |
| 4093 |
#if defined(_WIN32) && PARAVIEW_VERSION_MAJOR >= 3 |
| 4094 |
const vtkStdString pathFindSeparator = "/\\", pathSeparator = "\\"; |
| 4095 |
#else |
| 4096 |
const vtkStdString pathFindSeparator = "/", pathSeparator = "/"; |
| 4097 |
#endif |
| 4098 |
vtkStdString path(pathIn); |
| 4099 |
|
| 4100 |
// determine the case directory and path to controlDict |
| 4101 |
size_t pos = path.find_last_of(pathFindSeparator); |
| 4102 |
if(pos == vtkStdString::npos) |
| 4103 |
{ |
| 4104 |
// if there's no prepending path, prefix with the current directory |
| 4105 |
path = "." + pathSeparator + path; |
| 4106 |
pos = 1; |
| 4107 |
} |
| 4108 |
if(path.substr(pos + 1, 11) == "controlDict") |
| 4109 |
{ |
| 4110 |
// remove trailing "/controlDict*" |
| 4111 |
*this->PathPrefix = path.substr(0, pos - 1); |
| 4112 |
if(*this->PathPrefix == ".") |
| 4113 |
{ |
| 4114 |
*this->PathPrefix = ".." + pathSeparator; |
| 4115 |
} |
| 4116 |
else |
| 4117 |
{ |
| 4118 |
pos = this->PathPrefix->find_last_of(pathFindSeparator); |
| 4119 |
if(pos == vtkStdString::npos) |
| 4120 |
{ |
| 4121 |
*this->PathPrefix = "." + pathSeparator; |
| 4122 |
} |
| 4123 |
else |
| 4124 |
{ |
| 4125 |
// remove trailing "system" (or any other directory name) |
| 4126 |
this->PathPrefix->erase(pos + 1); // preserve the last "/" |
| 4127 |
} |
| 4128 |
} |
| 4129 |
} |
| 4130 |
else |
| 4131 |
{ |
| 4132 |
// if the file is named other than controlDict*, use the directory |
| 4133 |
// containing the file as case directory |
| 4134 |
*this->PathPrefix = path.substr(0, pos + 1); |
| 4135 |
path = *this->PathPrefix + "system" + pathSeparator + "controlDict"; |
| 4136 |
} |
| 4137 |
|
| 4138 |
// list timesteps (skip parsing controlDict entirely if |
| 4139 |
// ListTimeStepsByControlDict is set to 0) |
| 4140 |
if(this->ListTimeStepsByControlDict) |
| 4141 |
{ |
| 4142 |
vtkFoamIOobject io(*this->PathPrefix); |
| 4143 |
|
| 4144 |
// open and check if controlDict is readable |
| 4145 |
if(!io.open(path)) |
| 4146 |
{ |
| 4147 |
vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": " |
| 4148 |
<< io.error().c_str()); |
| 4149 |
return false; |
| 4150 |
} |
| 4151 |
vtkFoamDict dict; |
| 4152 |
if(!dict.read(io)) |
| 4153 |
{ |
| 4154 |
vtkErrorMacro(<<"Error reading line " << io.lineNumber() |
| 4155 |
<< " of " << io.fileName().c_str() << ": " << io.error().c_str()); |
| 4156 |
return false; |
| 4157 |
} |
| 4158 |
if(dict.type() != vtkFoamToken::DICTIONARY) |
| 4159 |
{ |
| 4160 |
vtkErrorMacro(<<"The file type of " << io.fileName().c_str() |
| 4161 |
<< " is not a dictionary"); |
| 4162 |
return false; |
| 4163 |
} |
| 4164 |
|
| 4165 |
vtkFoamEntry& writeControlEntry = dict.lookup("writeControl"); |
| 4166 |
if(!writeControlEntry.found()) |
| 4167 |
{ |
| 4168 |
vtkErrorMacro(<< "writeControl entry not found in " << pathIn); |
| 4169 |
return false; |
| 4170 |
} |
| 4171 |
const vtkStdString writeControl(writeControlEntry.toString()); |
| 4172 |
|
| 4173 |
// empty if not found |
| 4174 |
const vtkStdString adjustTimeStep(dict.lookup("adjustTimeStep").toString()); |
| 4175 |
|
| 4176 |
// list time directories according to controlDict if (adjustTimeStep |
| 4177 |
// writeControl) == (off, timeStep) or (on, adjustableRunTime); list |
| 4178 |
// by time instances in the case directory otherwise (different behavior |
| 4179 |
// from paraFoam) |
| 4180 |
// valid switching words cf. src/OpenFOAM/db/Switch/Switch.C |
| 4181 |
if((((adjustTimeStep == "off" || adjustTimeStep == "no" |
| 4182 |
|| adjustTimeStep == "n" || adjustTimeStep == "false" |
| 4183 |
|| adjustTimeStep == "") && writeControl == "timeStep") |
| 4184 |
|| ((adjustTimeStep == "on" || adjustTimeStep == "yes" |
| 4185 |
|| adjustTimeStep == "y" || adjustTimeStep == "true") |
| 4186 |
&& writeControl == "adjustableRunTime"))) |
| 4187 |
{ |
| 4188 |
return this->ListTimeDirectoriesByControlDict(&dict); |
| 4189 |
} |
| 4190 |
else |
| 4191 |
{ |
| 4192 |
return this->ListTimeDirectoriesByInstances(); |
| 4193 |
} |
| 4194 |
} |
| 4195 |
|
| 4196 |
return this->ListTimeDirectoriesByInstances(); |
| 4197 |
} |
| 4198 |
|
| 4199 |
//----------------------------------------------------------------------------- |
| 4200 |
void vtkOpenFOAMReader::AppendMeshDirToArray(vtkStringArray* polyMeshDir, |
| 4201 |
const char *pathIn, const int timeI) |
| 4202 |
{ |
| 4203 |
vtkStdString path(pathIn); |
| 4204 |
vtkFoamIOobject io(*this->PathPrefix); |
| 4205 |
|
| 4206 |
if(io.open(path) || io.open(path + ".gz")) |
| 4207 |
{ |
| 4208 |
io.close(); |
| 4209 |
// set points/faces location to current timesteps value |
| 4210 |
polyMeshDir->SetValue(timeI, this->TimeNames->GetValue(timeI)); |
| 4211 |
} |
| 4212 |
else |
| 4213 |
{ |
| 4214 |
if(timeI != 0) |
| 4215 |
{ |
| 4216 |
// set points/faces location to previous timesteps value |
| 4217 |
polyMeshDir->SetValue(timeI, polyMeshDir->GetValue(timeI - 1)); |
| 4218 |
} |
| 4219 |
else |
| 4220 |
{ |
| 4221 |
// set points/faces to constant |
| 4222 |
polyMeshDir->SetValue(timeI, "constant"); |
| 4223 |
} |
| 4224 |
} |
| 4225 |
} |
| 4226 |
|
| 4227 |
//----------------------------------------------------------------------------- |
| 4228 |
// create a Lookup Table containing the location of the points |
| 4229 |
// and faces files for each time steps mesh |
| 4230 |
void vtkOpenFOAMReader::PopulatePolyMeshDirArrays() |
| 4231 |
{ |
| 4232 |
vtkDebugMacro(<<"Create list of points/faces file directories"); |
| 4233 |
|
| 4234 |
// intialize size to number of timesteps |
| 4235 |
this->PolyMeshPointsDir->SetNumberOfValues(this->NumberOfTimeSteps); |
| 4236 |
this->PolyMeshFacesDir->SetNumberOfValues(this->NumberOfTimeSteps); |
| 4237 |
|
| 4238 |
// loop through each timestep |
| 4239 |
for(int i = 0; i < this->NumberOfTimeSteps; i++) |
| 4240 |
{ |
| 4241 |
// create the path to the timestep |
| 4242 |
vtkStdString polyMeshPath |
| 4243 |
= *this->PathPrefix + this->TimeNames->GetValue(i) + "/polyMesh/"; |
| 4244 |
AppendMeshDirToArray(this->PolyMeshPointsDir, |
| 4245 |
(polyMeshPath + "points").c_str(), i); |
| 4246 |
AppendMeshDirToArray(this->PolyMeshFacesDir, |
| 4247 |
(polyMeshPath + "faces").c_str(), i); |
| 4248 |
} |
| 4249 |
vtkDebugMacro(<<"Points/faces list created"); |
| 4250 |
return; |
| 4251 |
} |
| 4252 |
|
| 4253 |
//----------------------------------------------------------------------------- |
| 4254 |
// read the points file into a vtkFloatArray |
| 4255 |
vtkFloatArray* vtkOpenFOAMReader::ReadPointsFile(int timeState) |
| 4256 |
{ |
| 4257 |
// path to points file |
| 4258 |
vtkStdString pointPath = *this->PathPrefix + |
| 4259 |
this->PolyMeshPointsDir->GetValue(timeState) + "/polyMesh/points"; |
| 4260 |
vtkDebugMacro(<<"Read points file: "<<pointPath.c_str()); |
| 4261 |
|
| 4262 |
vtkFoamIOobject io(*this->PathPrefix); |
| 4263 |
if(!(io.open(pointPath) || io.open(pointPath + ".gz"))) |
| 4264 |
{ |
| 4265 |
vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": " |
| 4266 |
<< io.error().c_str()); |
| 4267 |
return NULL; |
| 4268 |
} |
| 4269 |
vtkFoamDict dict; |
| 4270 |
if(!dict.read(io)) |
| 4271 |
{ |
| 4272 |
vtkErrorMacro(<<"Error reading line " << io.lineNumber() |
| 4273 |
<< " of " << io.fileName().c_str() << ": " << io.error().c_str()); |
| 4274 |
return NULL; |
| 4275 |
} |
| 4276 |
if(dict.type() != vtkFoamToken::VECTORLIST) |
| 4277 |
{ |
| 4278 |
vtkErrorMacro(<<"The file type of " << io.fileName().c_str() |
| 4279 |
<< " is not a vectorList"); |
| 4280 |
return NULL; |
| 4281 |
} |
| 4282 |
|
| 4283 |
vtkFloatArray *pointArray = static_cast<vtkFloatArray *>(dict.ptr()); |
| 4284 |
|
| 4285 |
// set the number of points |
| 4286 |
this->NumPoints = pointArray->GetNumberOfTuples(); |
| 4287 |
|
| 4288 |
vtkDebugMacro(<<"Point file read"); |
| 4289 |
return pointArray; |
| 4290 |
} |
| 4291 |
|
| 4292 |
//----------------------------------------------------------------------------- |
| 4293 |
// read the faces into a intVectorVector |
| 4294 |
vtkOpenFOAMReader::intVectorVector* vtkOpenFOAMReader::ReadFacesFile( |
| 4295 |
const char* facePathIn) |
| 4296 |
{ |
| 4297 |
const vtkStdString facePath(facePathIn); |
| 4298 |
vtkDebugMacro(<<"Read faces file: "<<facePath.c_str()); |
| 4299 |
|
| 4300 |
vtkFoamIOobject io(*this->PathPrefix); |
| 4301 |
if(!(io.open(facePath) || io.open(facePath + ".gz"))) |
| 4302 |
{ |
| 4303 |
vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": " |
| 4304 |
<< io.error().c_str()); |
| 4305 |
return NULL; |
| 4306 |
} |
| 4307 |
vtkFoamDict dict; |
| 4308 |
if(!dict.read(io)) |
| 4309 |
{ |
| 4310 |
vtkErrorMacro(<<"Error reading line " << io.lineNumber() |
| 4311 |
<< " of " << io.fileName().c_str() << ": " << io.error().c_str()); |
| 4312 |
return NULL; |
| 4313 |
} |
| 4314 |
if(dict.type() != vtkFoamToken::LABELLISTLIST) |
| 4315 |
{ |
| 4316 |
vtkErrorMacro(<<"The file type of " << io.fileName().c_str() |
| 4317 |
<< " is not a labelListList"); |
| 4318 |
return NULL; |
| 4319 |
} |
| 4320 |
|
| 4321 |
vtkDebugMacro(<<"Faces read"); |
| 4322 |
return static_cast<intVectorVector *>(dict.ptr()); |
| 4323 |
} |
| 4324 |
|
| 4325 |
//----------------------------------------------------------------------------- |
| 4326 |
// read the owner and neighbor file and create cellFaces |
| 4327 |
bool vtkOpenFOAMReader::ReadOwnerNeighborFiles(vtkIntArray *cellFacesList, |
| 4328 |
vtkIntArray *cellFacesIndices, const char* ownerPathIn, |
| 4329 |
const char* neighborPathIn) |
| 4330 |
{ |
| 4331 |
const vtkStdString ownerPath(ownerPathIn); |
| 4332 |
vtkDebugMacro(<<"Read owner file: "<<ownerPath.c_str()); |
| 4333 |
|
| 4334 |
vtkFoamIOobject io(*this->PathPrefix); |
| 4335 |
if(!(io.open(ownerPath) || io.open(ownerPath + ".gz"))) |
| 4336 |
{ |
| 4337 |
vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": " |
| 4338 |
<< io.error().c_str()); |
| 4339 |
return false; |
| 4340 |
} |
| 4341 |
vtkFoamDict ownerDict; |
| 4342 |
if(!ownerDict.read(io)) |
| 4343 |
{ |
| 4344 |
vtkErrorMacro(<<"Error reading line " << io.lineNumber() |
| 4345 |
<< " of " << io.fileName().c_str() << ": " << io.error().c_str()); |
| 4346 |
return false; |
| 4347 |
} |
| 4348 |
if(ownerDict.type() != vtkFoamToken::LABELLIST) |
| 4349 |
{ |
| 4350 |
vtkErrorMacro(<<"The file type of " << io.fileName().c_str() |
| 4351 |
<< " is not a labelList"); |
| 4352 |
return false; |
| 4353 |
} |
| 4354 |
io.close(); |
| 4355 |
|
| 4356 |
const vtkStdString neighborPath(neighborPathIn); |
| 4357 |
vtkDebugMacro(<<"Read neighbor file: "<<neighborPath.c_str()); |
| 4358 |
|
| 4359 |
if(!(io.open(neighborPath) || io.open(neighborPath + ".gz"))) |
| 4360 |
{ |
| 4361 |
vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": " |
| 4362 |
<< io.error().c_str()); |
| 4363 |
return false; |
| 4364 |
} |
| 4365 |
vtkFoamDict neighborDict; |
| 4366 |
if(!neighborDict.read(io)) |
| 4367 |
{ |
| 4368 |
vtkErrorMacro(<<"Error reading line " << io.lineNumber() |
| 4369 |
<< " of " << io.fileName().c_str() << ": " << io.error().c_str()); |
| 4370 |
return false; |
| 4371 |
} |
| 4372 |
if(neighborDict.type() != vtkFoamToken::LABELLIST) |
| 4373 |
{ |
| 4374 |
vtkErrorMacro(<<"The file type of " << io.fileName().c_str() |
| 4375 |
<< " is not a labelList"); |
| 4376 |
return false; |
| 4377 |
} |
| 4378 |
|
| 4379 |
this->FaceOwner = static_cast<vtkIntArray *>(ownerDict.ptr()); |
| 4380 |
vtkIntArray &faceOwner = *this->FaceOwner; |
| 4381 |
vtkIntArray &faceNeighbor = neighborDict.labelList(); |
| 4382 |
|
| 4383 |
const int nFaces = faceOwner.GetNumberOfTuples(); |
| 4384 |
const int nNeiFaces = faceNeighbor.GetNumberOfTuples(); |
| 4385 |
|
| 4386 |
if(nFaces < nNeiFaces) |
| 4387 |
{ |
| 4388 |
vtkErrorMacro(<<"Numbers of owner faces (" << nFaces |
| 4389 |
<< ") must be equal or larger than number of neighbor faces (" |
| 4390 |
<< nNeiFaces << ")"); |
| 4391 |
return false; |
| 4392 |
} |
| 4393 |
|
| 4394 |
if(nFaces == 0) |
| 4395 |
{ |
| 4396 |
vtkWarningMacro(<<"The mesh contains no faces"); |
| 4397 |
} |
| 4398 |
|
| 4399 |
// add the face numbers to the correct cell |
| 4400 |
// cf. Terry's code and src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCells.C |
| 4401 |
|
| 4402 |
// find the number of cells |
| 4403 |
int nCells = -1; |
| 4404 |
for(int faceI = 0; faceI < nNeiFaces; faceI++) |
| 4405 |
{ |
| 4406 |
const int ownerCell = faceOwner.GetValue(faceI); |
| 4407 |
if(nCells < ownerCell) // max(nCells, faceOwner[i]) |
| 4408 |
{ |
| 4409 |
nCells = ownerCell; |
| 4410 |
} |
| 4411 |
// we do need to take neighbor faces into account since all the |
| 4412 |
// surrounding faces of a cell can be neighbors for a valid mesh |
| 4413 |
const int neighborCell = faceNeighbor.GetValue(faceI); |
| 4414 |
if(nCells < neighborCell) // max(nCells, faceNeighbor[i]) |
| 4415 |
{ |
| 4416 |
nCells = neighborCell; |
| 4417 |
} |
| 4418 |
} |
| 4419 |
for(int faceI = nNeiFaces; faceI < nFaces; faceI++) |
| 4420 |
{ |
| 4421 |
const int ownerCell = faceOwner.GetValue(faceI); |
| 4422 |
if(nCells < ownerCell) // max(nCells, faceOwner[i]) |
| 4423 |
{ |
| 4424 |
nCells = ownerCell; |
| 4425 |
} |
| 4426 |
} |
| 4427 |
nCells++; |
| 4428 |
|
| 4429 |
if(nCells == 0) |
| 4430 |
{ |
| 4431 |
vtkWarningMacro(<<"The mesh contains no cells"); |
| 4432 |
} |
| 4433 |
|
| 4434 |
// set the number of cells |
| 4435 |
this->NumCells = nCells; |
| 4436 |
|
| 4437 |
// count number of faces for each cell |
| 4438 |
cellFacesIndices->SetNumberOfValues(nCells + 1); |
| 4439 |
int *cfiPtr = cellFacesIndices->GetPointer(0); |
| 4440 |
for(int cellI = 0; cellI <= nCells; cellI++) |
| 4441 |
{ |
| 4442 |
cfiPtr[cellI] = 0; |
| 4443 |
} |
| 4444 |
int nTotalCellFaces = 0; |
| 4445 |
cfiPtr++; // offset +1 |
| 4446 |
for(int faceI = 0; faceI < nNeiFaces; faceI++) |
| 4447 |
{ |
| 4448 |
const int ownerCell = faceOwner.GetValue(faceI); |
| 4449 |
// simpleFoam/pitzDaily3Blocks has faces with owner cell number -1 |
| 4450 |
if(ownerCell >= 0) |
| 4451 |
{ |
| 4452 |
cfiPtr[ownerCell]++; |
| 4453 |
nTotalCellFaces++; |
| 4454 |
} |
| 4455 |
const int neighborCell=faceNeighbor.GetValue(faceI); |
| 4456 |
if(neighborCell >= 0) |
| 4457 |
{ |
| 4458 |
cfiPtr[neighborCell]++; |
| 4459 |
nTotalCellFaces++; |
| 4460 |
} |
| 4461 |
} |
| 4462 |
for(int faceI = nNeiFaces; faceI < nFaces; faceI++) |
| 4463 |
{ |
| 4464 |
const int ownerCell = faceOwner.GetValue(faceI); |
| 4465 |
if(ownerCell >= 0) |
| 4466 |
{ |
| 4467 |
cfiPtr[ownerCell]++; |
| 4468 |
nTotalCellFaces++; |
| 4469 |
} |
| 4470 |
} |
| 4471 |
cfiPtr--; // revert offset +1 |
| 4472 |
|
| 4473 |
// allocate cellFaces. To reduce the numbers of new/delete operations we |
| 4474 |
// allocate memory space for all faces linearly |
| 4475 |
cellFacesList->SetNumberOfValues(nTotalCellFaces); |
| 4476 |
|
| 4477 |
// accumulate the number of cellFaces to create cellFaces indices |
| 4478 |
// and copy them to a temporary array |
| 4479 |
vtkIntArray *tmpFaceIndices = vtkIntArray::New(); |
| 4480 |
tmpFaceIndices->SetNumberOfValues(nCells + 1); |
| 4481 |
int *tfiPtr = tmpFaceIndices->GetPointer(0); |
| 4482 |
tfiPtr[0] = 0; |
| 4483 |
for(int cellI = 1; cellI <= nCells; cellI++) |
| 4484 |
{ |
| 4485 |
tfiPtr[cellI] = (cfiPtr[cellI] += cfiPtr[cellI - 1]); |
| 4486 |
} |
| 4487 |
|
| 4488 |
// add face numbers to cell-faces list |
| 4489 |
for(int faceI = 0; faceI < nNeiFaces; faceI++) |
| 4490 |
{ |
| 4491 |
const int ownerCell = faceOwner.GetValue(faceI); // must be a signed int |
| 4492 |
// simpleFoam/pitzDaily3Blocks has faces with owner cell number -1 |
| 4493 |
if(ownerCell >= 0) |
| 4494 |
{ |
| 4495 |
cellFacesList->SetValue(tfiPtr[ownerCell]++, faceI); |
| 4496 |
} |
| 4497 |
const int neighborCell = faceNeighbor.GetValue(faceI); |
| 4498 |
if(neighborCell >= 0) |
| 4499 |
{ |
| 4500 |
cellFacesList->SetValue(tfiPtr[neighborCell]++, faceI); |
| 4501 |
} |
| 4502 |
} |
| 4503 |
for(int faceI = nNeiFaces; faceI < nFaces; faceI++) |
| 4504 |
{ |
| 4505 |
const int ownerCell = faceOwner.GetValue(faceI); // must be a signed int |
| 4506 |
// simpleFoam/pitzDaily3Blocks has faces with owner cell number -1 |
| 4507 |
if(ownerCell >= 0) |
| 4508 |
{ |
| 4509 |
cellFacesList->SetValue(tfiPtr[ownerCell]++, faceI); |
| 4510 |
} |
| 4511 |
} |
| 4512 |
tmpFaceIndices->Delete(); |
| 4513 |
|
| 4514 |
vtkDebugMacro(<<"Owner and neighbour files read"); |
| 4515 |
return true; |
| 4516 |
} |
| 4517 |
|
| 4518 |
//----------------------------------------------------------------------------- |
| 4519 |
// determine cell shape and insert the cell into the mesh |
| 4520 |
// hexahedron, prism, pyramid, tetrahedron and decompose polyhedron |
| 4521 |
void vtkOpenFOAMReader::InsertCellsToGrid(vtkUnstructuredGrid* internalMesh, |
| 4522 |
vtkIntArray *cellFacesList, vtkIntArray *cellFacesIndices, |
| 4523 |
const intVectorVector *facesPoints, vtkFloatArray *pointArray, |
| 4524 |
vtkIdTypeArray *additionalCells, vtkIntArray *cellList) |
| 4525 |
{ |
| 4526 |
const int maxNPoints = 128; // assume max number of points per cell |
| 4527 |
vtkIdList* cellPoints = vtkIdList::New(); |
| 4528 |
cellPoints->SetNumberOfIds(maxNPoints); |
| 4529 |
const int nCells |
| 4530 |
= (cellList == NULL ? this->NumCells : cellList->GetNumberOfTuples()); |
| 4531 |
int nAdditionalPoints = 0; |
| 4532 |
|
| 4533 |
// alias |
| 4534 |
const intVectorVector& facePoints = *facesPoints; |
| 4535 |
|
| 4536 |
for(int cellI = 0; cellI < nCells ; cellI++) |
| 4537 |
{ |
| 4538 |
int cellId; |
| 4539 |
if(cellList == NULL) |
| 4540 |
{ |
| 4541 |
cellId = cellI; |
| 4542 |
} |
| 4543 |
else |
| 4544 |
{ |
| 4545 |
cellId = cellList->GetValue(cellI); |
| 4546 |
if(cellId >= this->NumCells) |
| 4547 |
{ |
| 4548 |
vtkWarningMacro(<<"cellLabels id " << cellId |
| 4549 |
<< " exceeds the number of cells " << nCells); |
| 4550 |
internalMesh->InsertNextCell(VTK_EMPTY_CELL, 0, |
| 4551 |
cellPoints->GetPointer(0)); |
| 4552 |
continue; |
| 4553 |
} |
| 4554 |
} |
| 4555 |
const int cfi = cellFacesIndices->GetValue(cellId); |
| 4556 |
const int *cellFaces = cellFacesList->GetPointer(cfi); |
| 4557 |
const int nCellFaces = cellFacesIndices->GetValue(cellId + 1) - cfi; |
| 4558 |
|
| 4559 |
// determine type of the cell |
| 4560 |
// cf. src/OpenFOAM/meshes/meshShapes/cellMatcher/{hex|prism|pyr|tet}- |
| 4561 |
// Matcher.C |
| 4562 |
int cellType = VTK_CONVEX_POINT_SET; |
| 4563 |
if(nCellFaces == 6) |
| 4564 |
{ |
| 4565 |
int j = 0; |
| 4566 |
for(; j < nCellFaces; j++) |
| 4567 |
{ |
| 4568 |
if(facePoints.size(cellFaces[j]) != 4) |
| 4569 |
{ |
| 4570 |
break; |
| 4571 |
} |
| 4572 |
} |
| 4573 |
if(j == nCellFaces) |
| 4574 |
{ |
| 4575 |
cellType = VTK_HEXAHEDRON; |
| 4576 |
} |
| 4577 |
} |
| 4578 |
else if(nCellFaces == 5) |
| 4579 |
{ |
| 4580 |
int nTris = 0, nQuads = 0; |
| 4581 |
for(int j = 0; j < nCellFaces; j++) |
| 4582 |
{ |
| 4583 |
const int nPoints = facePoints.size(cellFaces[j]); |
| 4584 |
if(nPoints == 3) |
| 4585 |
{ |
| 4586 |
nTris++; |
| 4587 |
} |
| 4588 |
else if(nPoints == 4) |
| 4589 |
{ |
| 4590 |
nQuads++; |
| 4591 |
} |
| 4592 |
else |
| 4593 |
{ |
| 4594 |
break; |
| 4595 |
} |
| 4596 |
} |
| 4597 |
if(nTris == 2 && nQuads == 3) |
| 4598 |
{ |
| 4599 |
cellType = VTK_WEDGE; |
| 4600 |
} |
| 4601 |
else if(nTris == 4 && nQuads == 1) |
| 4602 |
{ |
| 4603 |
cellType = VTK_PYRAMID; |
| 4604 |
} |
| 4605 |
} |
| 4606 |
else if(nCellFaces == 4) |
| 4607 |
{ |
| 4608 |
int j = 0; |
| 4609 |
for(; j < nCellFaces; j++) |
| 4610 |
{ |
| 4611 |
if(facePoints.size(cellFaces[j]) != 3) |
| 4612 |
{ |
| 4613 |
break; |
| 4614 |
} |
| 4615 |
} |
| 4616 |
if(j == nCellFaces) |
| 4617 |
{ |
| 4618 |
cellType = VTK_TETRA; |
| 4619 |
} |
| 4620 |
} |
| 4621 |
|
| 4622 |
// not an Hex/Wedge/Pyramid/Tetra |
| 4623 |
if(cellType == VTK_CONVEX_POINT_SET) |
| 4624 |
{ |
| 4625 |
int nPoints = 0; |
| 4626 |
for(int j = 0; j < nCellFaces; j++) |
| 4627 |
{ |
| 4628 |
nPoints += facePoints.size(cellFaces[j]); |
| 4629 |
} |
| 4630 |
if(nPoints == 0) |
| 4631 |
{ |
| 4632 |
cellType = VTK_EMPTY_CELL; |
| 4633 |
} |
| 4634 |
} |
| 4635 |
|
| 4636 |
// Cell shape constructor based on the one implementd by Terry |
| 4637 |
// Jordan, with lots of improvements. Not as elegant as the one in |
| 4638 |
// OpenFOAM but it's simple and works reasonably fast. |
| 4639 |
|
| 4640 |
// OFhex | vtkHexahedron || OFprism | vtkWedge |
| 4641 |
if (cellType == VTK_HEXAHEDRON || cellType == VTK_WEDGE) |
| 4642 |
{ |
| 4643 |
// find the base face number |
| 4644 |
int baseFaceId = 8, nPoints; |
| 4645 |
if(cellType == VTK_HEXAHEDRON) |
| 4646 |
{ |
| 4647 |
nPoints = 8; |
| 4648 |
baseFaceId = 0; |
| 4649 |
} |
| 4650 |
else // VTK_WEDGE |
| 4651 |
{ |
| 4652 |
nPoints = 6; |
| 4653 |
for(int j = 0; j < nCellFaces; j++) |
| 4654 |
{ |
| 4655 |
if(facePoints.size(cellFaces[j]) == 3) |
| 4656 |
{ |
| 4657 |
baseFaceId = j; |
| 4658 |
break; |
| 4659 |
} |
| 4660 |
} |
| 4661 |
} |
| 4662 |
|
| 4663 |
// get first face in correct order |
| 4664 |
const int cellBaseFaceId = cellFaces[baseFaceId]; |
| 4665 |
const int *face0Points = facePoints[cellBaseFaceId]; |
| 4666 |
const int nBaseFacePoints = facePoints.size(cellBaseFaceId); |
| 4667 |
|
| 4668 |
if(this->FaceOwner->GetValue(cellBaseFaceId) == cellId) |
| 4669 |
{ |
| 4670 |
for(int j = 0; j < nBaseFacePoints; j++) |
| 4671 |
{ |
| 4672 |
cellPoints->SetId(j, face0Points[j]); |
| 4673 |
} |
| 4674 |
} |
| 4675 |
else |
| 4676 |
{ |
| 4677 |
// patch: if it is a neighbor face flip the points |
| 4678 |
for(int j = 0; j < nBaseFacePoints; j++) |
| 4679 |
{ |
| 4680 |
// add base face to cell points |
| 4681 |
cellPoints->SetId(j, face0Points[nBaseFacePoints - 1 - j]); |
| 4682 |
} |
| 4683 |
} |
| 4684 |
const int baseFacePoint0 = cellPoints->GetId(0); |
| 4685 |
const int baseFacePoint2 = cellPoints->GetId(2); |
| 4686 |
int oppositeFaceI = -1, pivotPoint = -1; |
| 4687 |
bool dupPoint2 = false; |
| 4688 |
for(int faceI = 0; faceI < nCellFaces; faceI++) |
| 4689 |
{ |
| 4690 |
if(faceI == baseFaceId) |
| 4691 |
{ |
| 4692 |
continue; |
| 4693 |
} |
| 4694 |
const int cellFaceI = cellFaces[faceI]; |
| 4695 |
const int *faceIPoints = facePoints[cellFaceI]; |
| 4696 |
const int nFaceIPoints = facePoints.size(cellFaceI); |
| 4697 |
bool found0Dup = false, found2Dup = false; |
| 4698 |
int pointI = 0; |
| 4699 |
for(; pointI < nFaceIPoints; pointI++) // each point |
| 4700 |
{ |
| 4701 |
const int faceIPointI = faceIPoints[pointI]; |
| 4702 |
// matching two points in base face is enough to find a |
| 4703 |
// duplicated point since neighboring faces share two |
| 4704 |
// neighboring points (i. e. an edge) |
| 4705 |
if(baseFacePoint0 == faceIPointI) |
| 4706 |
{ |
| 4707 |
found0Dup = true; |
| 4708 |
break; |
| 4709 |
} |
| 4710 |
else if(baseFacePoint2 == faceIPointI) |
| 4711 |
{ |
| 4712 |
found2Dup = true; |
| 4713 |
break; |
| 4714 |
} |
| 4715 |
} |
| 4716 |
if(found0Dup || found2Dup) |
| 4717 |
{ |
| 4718 |
// find the pivot point if still haven't |
| 4719 |
if(pivotPoint == -1) |
| 4720 |
{ |
| 4721 |
int baseFacePrevPoint, baseFaceNextPoint; |
| 4722 |
if(found0Dup) |
| 4723 |
{ |
| 4724 |
baseFacePrevPoint = cellPoints->GetId(nBaseFacePoints - 1); |
| 4725 |
baseFaceNextPoint = cellPoints->GetId(1); |
| 4726 |
} |
| 4727 |
else |
| 4728 |
{ |
| 4729 |
baseFacePrevPoint = cellPoints->GetId(1); |
| 4730 |
baseFaceNextPoint |
| 4731 |
= cellPoints->GetId(nBaseFacePoints == 3 ? 0 : 3); |
| 4732 |
dupPoint2 = true; |
| 4733 |
} |
| 4734 |
|
| 4735 |
const int faceINextPoint = faceIPoints[(pointI + 1) % nFaceIPoints]; |
| 4736 |
const int faceIPrevPoint |
| 4737 |
= faceIPoints[(nFaceIPoints + pointI - 1) % nFaceIPoints]; |
| 4738 |
|
| 4739 |
// if the next point of the faceI-th face matches the |
| 4740 |
// previous point of the base face use the previous point |
| 4741 |
// of the faceI-th face as the pivot point; or use the |
| 4742 |
// next point otherwise |
| 4743 |
if(faceINextPoint == (this->FaceOwner->GetValue(cellFaceI) |
| 4744 |
== cellId ? baseFacePrevPoint : baseFaceNextPoint)) |
| 4745 |
{ |
| 4746 |
pivotPoint = faceIPrevPoint; |
| 4747 |
} |
| 4748 |
else |
| 4749 |
{ |
| 4750 |
pivotPoint = faceINextPoint; |
| 4751 |
} |
| 4752 |
} |
| 4753 |
} |
| 4754 |
else |
| 4755 |
{ |
| 4756 |
// if no duplicated point found, faceI is the opposite face |
| 4757 |
if(oppositeFaceI == -1) |
| 4758 |
{ |
| 4759 |
oppositeFaceI = faceI; |
| 4760 |
} |
| 4761 |
} |
| 4762 |
|
| 4763 |
// break when both of opposite face and pivot point are found |
| 4764 |
if(oppositeFaceI >= 0 && pivotPoint >= 0) |
| 4765 |
{ |
| 4766 |
break; |
| 4767 |
} |
| 400 |
} |
4768 |
} |
| 401 |
|
4769 |
|
| 402 |
//patch: if it is a neighbor face flip the points |
4770 |
// find the pivot point in opposite face |
| 403 |
if(this->FacesOfCell->value[i][0].neighborFace) |
4771 |
const int cellOppositeFaceI = cellFaces[oppositeFaceI]; |
|
|
4772 |
const int *oppositeFacePoints = facePoints[cellOppositeFaceI]; |
| 4773 |
const int nOppositeFacePoints = facePoints.size(cellOppositeFaceI); |
| 4774 |
int pivotPointI = 0; |
| 4775 |
for(; pivotPointI < nOppositeFacePoints; pivotPointI++) |
| 404 |
{ |
4776 |
{ |
| 405 |
int tempPop; |
4777 |
if(oppositeFacePoints[pivotPointI] == pivotPoint) |
| 406 |
for(k = 0; k < (int)firstFace.size() - 1; k++) |
|
|
| 407 |
{ |
4778 |
{ |
| 408 |
tempPop = firstFace[firstFace.size()-1]; |
4779 |
break; |
| 409 |
firstFace.pop_back(); |
|
|
| 410 |
firstFace.insert(firstFace.begin()+1+k, tempPop); |
| 411 |
} |
4780 |
} |
| 412 |
} |
4781 |
} |
| 413 |
|
4782 |
|
| 414 |
//add first face to cell points |
4783 |
if(this->FaceOwner->GetValue(cellOppositeFaceI) == cellId) |
| 415 |
for(j =0; j < (int)firstFace.size(); j++) |
|
|
| 416 |
{ |
4784 |
{ |
| 417 |
cellPoints.push_back(firstFace[j]); |
4785 |
if(dupPoint2) |
|
|
4786 |
{ |
| 4787 |
pivotPointI = (pivotPointI + 2) % nOppositeFacePoints; |
| 4788 |
} |
| 4789 |
int basePointI = nBaseFacePoints; |
| 4790 |
for(int pointI = pivotPointI; pointI >= 0; pointI--) |
| 4791 |
{ |
| 4792 |
cellPoints->SetId(basePointI++, oppositeFacePoints[pointI]); |
| 4793 |
} |
| 4794 |
for(int pointI = nOppositeFacePoints - 1; pointI > pivotPointI; |
| 4795 |
pointI--) |
| 4796 |
{ |
| 4797 |
cellPoints->SetId(basePointI++, oppositeFacePoints[pointI]); |
| 4798 |
} |
| 418 |
} |
4799 |
} |
| 419 |
|
4800 |
else |
| 420 |
//find the opposite face and order the points correctly |
|
|
| 421 |
for(int pointCount = 0; pointCount < (int)firstFace.size(); pointCount++) |
| 422 |
{ |
4801 |
{ |
| 423 |
|
4802 |
// shift the pivot point if the point corresponds to point 2 |
| 424 |
//find the other 2 faces containing each point |
4803 |
// of the base face |
| 425 |
for(j = 1; j < (int)this->FacesOfCell->value[i].size(); j++) //each face |
4804 |
if(dupPoint2) |
| 426 |
{ |
4805 |
{ |
| 427 |
for(k = 0; k < (int)this->FacePoints->value[ |
4806 |
pivotPointI = (nOppositeFacePoints + pivotPointI - 2) |
| 428 |
this->FacesOfCell->value[i][j].faceIndex].size(); k++) //each point |
4807 |
% nOppositeFacePoints; |
| 429 |
{ |
|
|
| 430 |
if(firstFace[pointCount] == this->FacePoints->value[ |
| 431 |
this->FacesOfCell->value[i][j].faceIndex][k]) |
| 432 |
{ |
| 433 |
//ANOTHER FACE WITH THE POINT |
| 434 |
for(l = 0; l < (int)this->FacePoints->value[ |
| 435 |
this->FacesOfCell->value[i][j].faceIndex].size(); l++) |
| 436 |
{ |
| 437 |
tempFaces[faceCount].push_back(this->FacePoints->value[ |
| 438 |
this->FacesOfCell->value[i][j].faceIndex][l]); |
| 439 |
} |
| 440 |
faceCount++; |
| 441 |
} |
| 442 |
} |
| 443 |
} |
4808 |
} |
| 444 |
|
4809 |
// copy the face-point list of the opposite face to cell-point list |
| 445 |
//locate the pivot point contained in faces 0 & 1 |
4810 |
int basePointI = nBaseFacePoints; |
| 446 |
for(j = 0; j < (int)tempFaces[0].size(); j++) |
4811 |
for(int pointI = pivotPointI; pointI < nOppositeFacePoints; pointI++) |
| 447 |
{ |
4812 |
{ |
| 448 |
for(k = 0; k < (int)tempFaces[1].size(); k++) |
4813 |
cellPoints->SetId(basePointI++, oppositeFacePoints[pointI]); |
| 449 |
{ |
4814 |
} |
| 450 |
if(tempFaces[0][j] == tempFaces[1][k] && tempFaces[0][j] != |
4815 |
for(int pointI = 0; pointI < pivotPointI; pointI++) |
| 451 |
firstFace[pointCount]) |
4816 |
{ |
| 452 |
{ |
4817 |
cellPoints->SetId(basePointI++, oppositeFacePoints[pointI]); |
| 453 |
pivotPoint = tempFaces[0][j]; |
|
|
| 454 |
break; |
| 455 |
} |
| 456 |
} |
| 457 |
} |
4818 |
} |
| 458 |
cellPoints.push_back(pivotPoint); |
|
|
| 459 |
tempFaces[0].clear(); |
| 460 |
tempFaces[1].clear(); |
| 461 |
faceCount=0; |
| 462 |
} |
4819 |
} |
| 463 |
|
4820 |
|
| 464 |
//create the hex cell and insert it into the mesh |
4821 |
// create the hex cell and insert it into the mesh |
| 465 |
vtkHexahedron * hexahedron= vtkHexahedron::New(); |
4822 |
internalMesh->InsertNextCell(cellType, nPoints, |
| 466 |
for(pCount = 0; pCount < (int)cellPoints.size(); pCount++) |
4823 |
cellPoints->GetPointer(0)); |
| 467 |
{ |
|
|
| 468 |
hexahedron->GetPointIds()->SetId(pCount, cellPoints[pCount]); |
| 469 |
} |
| 470 |
internalMesh->InsertNextCell(hexahedron->GetCellType(), |
| 471 |
hexahedron->GetPointIds()); |
| 472 |
hexahedron->Delete(); |
| 473 |
cellPoints.clear(); |
| 474 |
firstFace.clear(); |
| 475 |
} |
4824 |
} |
| 476 |
|
4825 |
|
| 477 |
//OFprism | vtkWedge |
4826 |
// OFpyramid | vtkPyramid || OFtet | vtkTetrahedron |
| 478 |
else if (totalPointCount == 18) |
4827 |
else if (cellType == VTK_PYRAMID || cellType == VTK_TETRA) |
| 479 |
{ |
4828 |
{ |
| 480 |
faceCount = 0; |
4829 |
int baseFaceId = -1, nPoints; |
| 481 |
int index = 0; |
4830 |
if(cellType == VTK_PYRAMID) |
| 482 |
|
|
|
| 483 |
//find first triangular face |
| 484 |
for(j = 0; j < (int)this->FacesOfCell->value[i].size(); j++) //each face |
| 485 |
{ |
4831 |
{ |
| 486 |
if((int)this->FacePoints-> |
4832 |
for(int j = 0; j < nCellFaces; j++) |
| 487 |
value[this->FacesOfCell->value[i][j].faceIndex].size() == 3) |
|
|
| 488 |
{ |
4833 |
{ |
| 489 |
for(k = 0; k < (int)this->FacePoints->value[ |
4834 |
if(facePoints.size(cellFaces[j]) == 4) |
| 490 |
this->FacesOfCell->value[i][j].faceIndex].size(); k++) |
|
|
| 491 |
{ |
4835 |
{ |
| 492 |
firstFace.push_back(this->FacePoints->value[ |
4836 |
baseFaceId = j; |
| 493 |
this->FacesOfCell->value[i][j].faceIndex][k]); |
4837 |
break; |
| 494 |
index = j; |
|
|
| 495 |
} |
4838 |
} |
| 496 |
break; |
|
|
| 497 |
} |
4839 |
} |
|
|
4840 |
nPoints = 5; |
| 4841 |
} |
| 4842 |
else // VTK_TETRA |
| 4843 |
{ |
| 4844 |
baseFaceId = 0; |
| 4845 |
nPoints = 4; |
| 498 |
} |
4846 |
} |
| 499 |
|
4847 |
|
| 500 |
//patch: if it is a neighbor face flip the points |
4848 |
// add first face to cell points |
| 501 |
if(this->FacesOfCell->value[i][0].neighborFace) |
4849 |
const int cellBaseFaceId = cellFaces[baseFaceId]; |
|
|
4850 |
const int *baseFacePoints = facePoints[cellBaseFaceId]; |
| 4851 |
const size_t nBaseFacePoints = facePoints.size(cellBaseFaceId); |
| 4852 |
if(this->FaceOwner->GetValue(cellBaseFaceId) == cellId) |
| 502 |
{ |
4853 |
{ |
| 503 |
int tempPop; |
4854 |
for(size_t j = 0; j < nBaseFacePoints; j++) |
| 504 |
for(k = 0; k < (int)firstFace.size() - 1; k++) |
|
|
| 505 |
{ |
4855 |
{ |
| 506 |
tempPop = firstFace[firstFace.size()-1]; |
4856 |
cellPoints->SetId(j, baseFacePoints[j]); |
| 507 |
firstFace.pop_back(); |
4857 |
} |
| 508 |
firstFace.insert(firstFace.begin()+1+k, tempPop); |
4858 |
} |
|
|
4859 |
else |
| 4860 |
{ |
| 4861 |
// if it is a neighbor face flip the points |
| 4862 |
for(size_t j = 0; j < nBaseFacePoints; j++) |
| 4863 |
{ |
| 4864 |
cellPoints->SetId(j, baseFacePoints[nBaseFacePoints - 1 - j]); |
| 509 |
} |
4865 |
} |
| 510 |
} |
4866 |
} |
| 511 |
|
4867 |
|
| 512 |
//add first face to cell points |
4868 |
// compare an adjacent face (any non base face is ok) point 1 to |
| 513 |
for(j =0; j < (int)firstFace.size(); j++) |
4869 |
// base face points |
|
|
4870 |
const int adjacentFaceId = (baseFaceId == 0) ? 1 : baseFaceId - 1; |
| 4871 |
const int cellAdjacentFaceId = cellFaces[adjacentFaceId]; |
| 4872 |
const int *adjacentFacePoints = facePoints[cellAdjacentFaceId]; |
| 4873 |
const int adjacentFacePoint1 = adjacentFacePoints[1]; |
| 4874 |
bool foundDup = false; |
| 4875 |
for(size_t j = 0; j < nBaseFacePoints; j++) |
| 4876 |
{ |
| 4877 |
// if point 1 of the adjacent face matches point j of the base face... |
| 4878 |
if(cellPoints->GetId(j) == adjacentFacePoint1) |
| 4879 |
{ |
| 4880 |
// if point 2 of the adjacent face matches the previous point |
| 4881 |
// of the base face use point 0 of the adjacent face as the |
| 4882 |
// pivot point; use point 2 otherwise |
| 4883 |
cellPoints->SetId(nBaseFacePoints, (adjacentFacePoints[2] |
| 4884 |
== cellPoints->GetId((this->FaceOwner->GetValue(cellAdjacentFaceId) |
| 4885 |
== cellId ? (nBaseFacePoints + j - 1) : (j + 1)) % nBaseFacePoints)) |
| 4886 |
? adjacentFacePoints[0] : adjacentFacePoints[2]); |
| 4887 |
foundDup = true; |
| 4888 |
break; |
| 4889 |
} |
| 4890 |
} |
| 4891 |
// if point 1 of the adjacent face does not match any points of |
| 4892 |
// the base face, it's the pivot point |
| 4893 |
if(!foundDup) |
| 514 |
{ |
4894 |
{ |
| 515 |
cellPoints.push_back(firstFace[j]); |
4895 |
cellPoints->SetId(nBaseFacePoints, adjacentFacePoint1); |
| 516 |
} |
4896 |
} |
| 517 |
|
4897 |
|
| 518 |
//find the opposite face and order the points correctly |
4898 |
// create the tetra cell and insert it into the mesh |
| 519 |
for(int pointCount = 0; pointCount < (int)firstFace.size(); pointCount++) |
4899 |
internalMesh->InsertNextCell(cellType, nPoints, |
|
|
4900 |
cellPoints->GetPointer(0)); |
| 4901 |
} |
| 4902 |
|
| 4903 |
// erronous cells |
| 4904 |
else if(cellType == VTK_EMPTY_CELL) |
| 4905 |
{ |
| 4906 |
vtkWarningMacro("Warning: No points in cellId " << cellId); |
| 4907 |
internalMesh->InsertNextCell(VTK_EMPTY_CELL, 0, |
| 4908 |
cellPoints->GetPointer(0)); |
| 4909 |
} |
| 4910 |
|
| 4911 |
// OFpolyhedron || vtkConvexPointSet |
| 4912 |
else |
| 4913 |
{ |
| 4914 |
if(additionalCells != NULL) // decompose into tets and pyramids |
| 520 |
{ |
4915 |
{ |
| 521 |
//find the 2 other faces containing each point |
4916 |
// calculate cell centroid and insert it to point list |
| 522 |
for(j = 0; j < (int)this->FacesOfCell->value[i].size(); j++) //each face |
4917 |
this->AdditionalCellPoints->push_back(vtkIntArray::New()); |
|
|
4918 |
vtkIntArray *polyCellPoints = this->AdditionalCellPoints->back(); |
| 4919 |
float centroid[3]; |
| 4920 |
centroid[0] = centroid[1] = centroid[2] = 0.0F; |
| 4921 |
for(int j = 0; j < nCellFaces; j++) |
| 523 |
{ |
4922 |
{ |
| 524 |
for(k = 0; k < (int)this->FacePoints->value[ |
4923 |
// remove duplicate points from faces |
| 525 |
this->FacesOfCell->value[i][j].faceIndex].size(); k++) |
4924 |
const int cellFacesJ = cellFaces[j]; |
|
|
4925 |
const int *faceJPoints = facePoints[cellFacesJ]; |
| 4926 |
const size_t nFaceJPoints = facePoints.size(cellFacesJ); |
| 4927 |
for(size_t k = 0; k < nFaceJPoints; k++) |
| 526 |
{ |
4928 |
{ |
| 527 |
if(firstFace[pointCount] == this->FacePoints->value[ |
4929 |
const int faceJPointK = faceJPoints[k]; |
| 528 |
this->FacesOfCell->value[i][j].faceIndex][k] && j != index) |
4930 |
bool foundDup = false; |
|
|
4931 |
for(size_t l = 0; l < polyCellPoints->GetDataSize(); l++) |
| 529 |
{ |
4932 |
{ |
| 530 |
//ANOTHER FACE WITH POINT |
4933 |
if(polyCellPoints->GetValue(l) == faceJPointK) |
| 531 |
for(l = 0; l < (int)this->FacePoints->value[ |
|
|
| 532 |
this->FacesOfCell->value[i][j].faceIndex].size(); l++) |
| 533 |
{ |
4934 |
{ |
| 534 |
tempFaces[faceCount].push_back(this->FacePoints->value[ |
4935 |
foundDup = true; |
| 535 |
this->FacesOfCell->value[i][j].faceIndex][l]); |
4936 |
break; // look no more |
| 536 |
} |
4937 |
} |
| 537 |
faceCount++; |
4938 |
} |
|
|
4939 |
if(!foundDup) |
| 4940 |
{ |
| 4941 |
polyCellPoints->InsertNextValue(faceJPointK); |
| 4942 |
float *pointK = pointArray->GetPointer(3 * faceJPointK); |
| 4943 |
centroid[0] += pointK[0]; |
| 4944 |
centroid[1] += pointK[1]; |
| 4945 |
centroid[2] += pointK[2]; |
| 538 |
} |
4946 |
} |
| 539 |
} |
4947 |
} |
| 540 |
} |
4948 |
} |
| 541 |
|
4949 |
polyCellPoints->Squeeze(); |
| 542 |
//locate the pivot point of faces 0 & 1 |
4950 |
float weight = 1.0F / static_cast<float>(polyCellPoints->GetDataSize()); |
| 543 |
for(j = 0; j < (int)tempFaces[0].size(); j++) |
4951 |
centroid[0] *= weight; |
|
|
4952 |
centroid[1] *= weight; |
| 4953 |
centroid[2] *= weight; |
| 4954 |
pointArray->InsertNextTuple(centroid); |
| 4955 |
|
| 4956 |
// polyhedron decomposition. |
| 4957 |
// a tweaked algorithm based on applications/utilities/postProcessing/ |
| 4958 |
// graphics/PVFoamReader/vtkFoam/vtkFoamAddInternalMesh.C |
| 4959 |
bool insertDecomposedCell = true; |
| 4960 |
for(int j = 0; j < nCellFaces; j++) |
| 544 |
{ |
4961 |
{ |
| 545 |
for(k = 0; k < (int)tempFaces[1].size(); k++) |
4962 |
const int cellFacesJ = cellFaces[j]; |
|
|
4963 |
const int *faceJPoints = facePoints[cellFacesJ]; |
| 4964 |
const int nFaceJPoints = facePoints.size(cellFacesJ); |
| 4965 |
const int flipNeighbor |
| 4966 |
= (this->FaceOwner->GetValue(cellFacesJ) == cellId ? 1 : -1); |
| 4967 |
const int nTris = nFaceJPoints % 2; |
| 4968 |
|
| 4969 |
int vertI = 2; |
| 4970 |
|
| 4971 |
// shift the start and end of the vertex loop if the |
| 4972 |
// triangle of a decomposed face is going to be flat. Far |
| 4973 |
// from perfect but better than nothing to avoid flat cells |
| 4974 |
// which stops time integration of Stream Tracer especially |
| 4975 |
// for split-hex unstructured meshes created by |
| 4976 |
// e. g. autoRefineMesh |
| 4977 |
if(nFaceJPoints >= 5 && nTris) |
| 546 |
{ |
4978 |
{ |
| 547 |
if(tempFaces[0][j] == tempFaces[1][k] && tempFaces[0][j] != |
4979 |
float *point0, *point1, *point2; |
| 548 |
firstFace[pointCount]) |
4980 |
point0 = pointArray->GetPointer(3 * faceJPoints[nFaceJPoints - 1]); |
|
|
4981 |
point1 = pointArray->GetPointer(3 * faceJPoints[0]); |
| 4982 |
point2 = pointArray->GetPointer(3 * faceJPoints[nFaceJPoints - 2]); |
| 4983 |
float vsizeSqr1 = 0.0F, vsizeSqr2 = 0.0F, dotProduct = 0.0F; |
| 4984 |
for(int i = 0; i < 3; i++) |
| 549 |
{ |
4985 |
{ |
| 550 |
pivotPoint = tempFaces[0][j]; |
4986 |
const float v1 = point1[i] - point0[i], |
| 551 |
break; |
4987 |
v2 = point2[i] - point0[i]; |
|
|
4988 |
vsizeSqr1 += v1 * v1; |
| 4989 |
vsizeSqr2 += v2 * v2; |
| 4990 |
dotProduct += v1 * v2; |
| 4991 |
} |
| 4992 |
// compare in squared representation to avoid using sqrt() |
| 4993 |
if(dotProduct * fabsf(dotProduct) / (vsizeSqr1 * vsizeSqr2) |
| 4994 |
< -1.0F + 1.0e-3F) |
| 4995 |
{ |
| 4996 |
vertI = 1; |
| 552 |
} |
4997 |
} |
| 553 |
} |
4998 |
} |
| 554 |
} |
|
|
| 555 |
cellPoints.push_back(pivotPoint); |
| 556 |
tempFaces[0].clear(); |
| 557 |
tempFaces[1].clear(); |
| 558 |
faceCount=0; |
| 559 |
} |
| 560 |
|
| 561 |
//create the wedge cell and insert it into the mesh |
| 562 |
vtkWedge * wedge= vtkWedge::New(); |
| 563 |
for(pCount = 0; pCount < (int)cellPoints.size(); pCount++) |
| 564 |
{ |
| 565 |
wedge->GetPointIds()->SetId(pCount, cellPoints[pCount]); |
| 566 |
} |
| 567 |
internalMesh->InsertNextCell(wedge->GetCellType(), |
| 568 |
wedge->GetPointIds()); |
| 569 |
cellPoints.clear(); |
| 570 |
wedge->Delete(); |
| 571 |
firstFace.clear(); |
| 572 |
} |
| 573 |
|
4999 |
|
| 574 |
//OFpyramid | vtkPyramid |
5000 |
cellPoints->SetId(0, faceJPoints[vertI == 2 ? 0 : nFaceJPoints - 1]); |
| 575 |
else if (totalPointCount == 16) |
5001 |
cellPoints->SetId(4, this->NumPoints + nAdditionalPoints); |
| 576 |
{ |
|
|
| 577 |
foundDup = false; |
| 578 |
|
5002 |
|
| 579 |
//find the quadratic face |
5003 |
// decompose a face into quads in order (flipping the |
| 580 |
for(j = 0; j < (int)this->FacesOfCell->value[i].size(); j++) //each face |
5004 |
// decomposed face if neighbor) |
| 581 |
{ |
5005 |
const int nQuadVerts = nFaceJPoints - 1 - nTris; |
| 582 |
if((int)this->FacePoints-> |
5006 |
for(; vertI < nQuadVerts; vertI += 2) |
| 583 |
value[this->FacesOfCell->value[i][j].faceIndex].size() == 4) |
|
|
| 584 |
{ |
| 585 |
for(k = 0; k < (int)this->FacePoints->value[ |
| 586 |
this->FacesOfCell->value[i][j].faceIndex].size(); k++) |
| 587 |
{ |
5007 |
{ |
| 588 |
cellPoints.push_back(this->FacePoints->value[ |
5008 |
cellPoints->SetId(1, faceJPoints[vertI - flipNeighbor]); |
| 589 |
this->FacesOfCell->value[i][j].faceIndex][k]); |
5009 |
cellPoints->SetId(2, faceJPoints[vertI]); |
|
|
5010 |
cellPoints->SetId(3, faceJPoints[vertI + flipNeighbor]); |
| 5011 |
|
| 5012 |
// if the decomposed cell is the first one insert it to |
| 5013 |
// the original position; or append to the decomposed cell |
| 5014 |
// list otherwise |
| 5015 |
if(insertDecomposedCell) |
| 5016 |
{ |
| 5017 |
internalMesh->InsertNextCell(VTK_PYRAMID, 5, |
| 5018 |
cellPoints->GetPointer(0)); |
| 5019 |
insertDecomposedCell = false; |
| 5020 |
} |
| 5021 |
else |
| 5022 |
{ |
| 5023 |
this->AdditionalCellIds->InsertNextValue(cellId); |
| 5024 |
additionalCells->InsertNextTupleValue(cellPoints->GetPointer(0)); |
| 5025 |
} |
| 590 |
} |
5026 |
} |
| 591 |
break; |
|
|
| 592 |
} |
| 593 |
} |
| 594 |
|
5027 |
|
| 595 |
//compare first face points to other faces |
5028 |
// if the number of vertices is odd there's a triangle |
| 596 |
for(j = 0; j < (int)cellPoints.size(); j++) //each point |
5029 |
if(nTris) |
| 597 |
{ |
|
|
| 598 |
for(k = 0; k < (int)this->FacePoints->value[ |
| 599 |
this->FacesOfCell->value[i][1].faceIndex].size(); k++) |
| 600 |
{ |
| 601 |
if(cellPoints[j] == this->FacePoints->value[ |
| 602 |
this->FacesOfCell->value[i][1].faceIndex][k]) |
| 603 |
{ |
5030 |
{ |
| 604 |
foundDup = true; |
5031 |
if(flipNeighbor == -1) |
|
|
5032 |
{ |
| 5033 |
cellPoints->SetId(1, faceJPoints[vertI]); |
| 5034 |
cellPoints->SetId(2, faceJPoints[vertI - 1]); |
| 5035 |
} |
| 5036 |
else |
| 5037 |
{ |
| 5038 |
cellPoints->SetId(1, faceJPoints[vertI - 1]); |
| 5039 |
cellPoints->SetId(2, faceJPoints[vertI]); |
| 5040 |
} |
| 5041 |
cellPoints->SetId(3, this->NumPoints + nAdditionalPoints); |
| 5042 |
|
| 5043 |
if(insertDecomposedCell) |
| 5044 |
{ |
| 5045 |
internalMesh->InsertNextCell(VTK_TETRA, 4, |
| 5046 |
cellPoints->GetPointer(0)); |
| 5047 |
insertDecomposedCell = false; |
| 5048 |
} |
| 5049 |
else |
| 5050 |
{ |
| 5051 |
// set the 5th vertex number to -1 to distinguish a tetra cell |
| 5052 |
cellPoints->SetId(4, -1); |
| 5053 |
this->AdditionalCellIds->InsertNextValue(cellId); |
| 5054 |
additionalCells->InsertNextTupleValue(cellPoints->GetPointer(0)); |
| 5055 |
} |
| 605 |
} |
5056 |
} |
| 606 |
} |
5057 |
} |
| 607 |
if(!foundDup) |
5058 |
nAdditionalPoints++; |
| 608 |
{ |
|
|
| 609 |
cellPoints.push_back(this->FacePoints->value[ |
| 610 |
this->FacesOfCell->value[i][j].faceIndex][k]); |
| 611 |
break; |
| 612 |
} |
| 613 |
} |
| 614 |
|
| 615 |
//create the pyramid cell and insert it into the mesh |
| 616 |
vtkPyramid * pyramid = vtkPyramid::New(); |
| 617 |
for(pCount = 0; pCount < (int)cellPoints.size(); pCount++) |
| 618 |
{ |
| 619 |
pyramid->GetPointIds()->SetId(pCount, cellPoints[pCount]); |
| 620 |
} |
5059 |
} |
| 621 |
internalMesh->InsertNextCell(pyramid->GetCellType(), |
5060 |
else // don't decompose; use VTK_CONVEX_PONIT_SET |
| 622 |
pyramid->GetPointIds()); |
|
|
| 623 |
cellPoints.clear(); |
| 624 |
pyramid->Delete(); |
| 625 |
} |
| 626 |
|
| 627 |
//OFtet | vtkTetrahedron |
| 628 |
else if (totalPointCount == 12) |
| 629 |
{ |
| 630 |
foundDup = false; |
| 631 |
|
| 632 |
//add first face to cell points |
| 633 |
for(j = 0; j < (int)this->FacePoints->value[ |
| 634 |
this->FacesOfCell->value[i][0].faceIndex].size(); j++) |
| 635 |
{ |
5061 |
{ |
| 636 |
cellPoints.push_back(this->FacePoints->value[ |
5062 |
// get first face |
| 637 |
this->FacesOfCell->value[i][0].faceIndex][j]); |
5063 |
const int cellFaces0 = cellFaces[0]; |
| 638 |
} |
5064 |
const int *baseFacePoints = facePoints[cellFaces0]; |
| 639 |
|
5065 |
const int nBaseFacePoints = facePoints.size(cellFaces0); |
| 640 |
//compare first face to the points of second face |
5066 |
int nPoints = nBaseFacePoints; |
| 641 |
for(j = 0; j < (int)cellPoints.size(); j++) //each point |
5067 |
if(nPoints > maxNPoints) |
| 642 |
{ |
5068 |
{ |
| 643 |
for(k = 0; k < (int)this->FacePoints->value[ |
5069 |
vtkErrorMacro(<< "Too large polyhedron at cellId = " << cellId); |
| 644 |
this->FacesOfCell->value[i][1].faceIndex].size(); k++) |
5070 |
return; |
|
|
5071 |
} |
| 5072 |
// add first face to cell points |
| 5073 |
// not sure if flipping is necessary but do it anyway |
| 5074 |
if(this->FaceOwner->GetValue(cellFaces0) == cellId) |
| 645 |
{ |
5075 |
{ |
| 646 |
if(cellPoints[j] == this->FacePoints->value[ |
5076 |
for(int j = 0; j < nBaseFacePoints; j++) |
| 647 |
this->FacesOfCell->value[i][1].faceIndex][k]) |
|
|
| 648 |
{ |
5077 |
{ |
| 649 |
foundDup = true; |
5078 |
cellPoints->SetId(j, baseFacePoints[j]); |
| 650 |
} |
5079 |
} |
| 651 |
} |
5080 |
} |
| 652 |
if(!foundDup) |
5081 |
else |
| 653 |
{ |
5082 |
{ |
| 654 |
cellPoints.push_back(this->FacePoints->value[ |
5083 |
// if it is a neighbor face flip the points |
| 655 |
this->FacesOfCell->value[i][j].faceIndex][k]); |
5084 |
for(int j = 0; j < nBaseFacePoints; j++) |
| 656 |
break; |
5085 |
{ |
|
|
5086 |
cellPoints->SetId(j, baseFacePoints[nBaseFacePoints - 1 - j]); |
| 5087 |
} |
| 657 |
} |
5088 |
} |
| 658 |
} |
|
|
| 659 |
|
| 660 |
//create the wedge cell and insert it into the mesh |
| 661 |
vtkTetra * tetra = vtkTetra::New(); |
| 662 |
for(pCount = 0; pCount < (int)cellPoints.size(); pCount++) |
| 663 |
{ |
| 664 |
tetra->GetPointIds()->SetId(pCount, cellPoints[pCount]); |
| 665 |
} |
| 666 |
internalMesh->InsertNextCell(tetra->GetCellType(), |
| 667 |
tetra->GetPointIds()); |
| 668 |
cellPoints.clear(); |
| 669 |
tetra->Delete(); |
| 670 |
} |
| 671 |
|
| 672 |
//erronous cells |
| 673 |
else if(totalPointCount == 0) |
| 674 |
{ |
| 675 |
vtkWarningMacro("Warning: No points in cell."); |
| 676 |
} |
| 677 |
|
| 678 |
//OFpolyhedron || vtkConvexPointSet |
| 679 |
else |
| 680 |
{ |
| 681 |
vtkWarningMacro("Warning: Polyhedral Data is very Slow!"); |
| 682 |
foundDup = false; |
| 683 |
|
5089 |
|
| 684 |
//get first face |
5090 |
// loop through faces and create a list of all points |
| 685 |
for(j = 0; j < (int)this->FacePoints->value[ |
5091 |
// j = 1 skip baseFace |
| 686 |
this->FacesOfCell->value[i][0].faceIndex].size(); j++) |
5092 |
for(int j = 1; j < nCellFaces; j++) |
| 687 |
{ |
|
|
| 688 |
firstFace.push_back(this->FacePoints->value[ |
| 689 |
this->FacesOfCell->value[i][0].faceIndex][j]); |
| 690 |
} |
| 691 |
|
| 692 |
//add first face to cell points |
| 693 |
for(j =0; j < (int)firstFace.size(); j++) |
| 694 |
{ |
| 695 |
cellPoints.push_back(firstFace[j]); |
| 696 |
} |
| 697 |
|
| 698 |
//loop through faces and create a list of all points |
| 699 |
//j = 1 skip firstFace |
| 700 |
for(j = 1; j < (int)this->FacesOfCell->value[i].size(); j++) |
| 701 |
{ |
| 702 |
//remove duplicate points from faces |
| 703 |
for(k = 0; k < (int)this->FacePoints->value[ |
| 704 |
this->FacesOfCell->value[i][j].faceIndex].size(); k++) |
| 705 |
{ |
5093 |
{ |
| 706 |
for(l = 0; l < (int)cellPoints.size(); l++); |
5094 |
// remove duplicate points from faces |
|
|
5095 |
const int cellFacesJ = cellFaces[j]; |
| 5096 |
const int *faceJPoints = facePoints[cellFacesJ]; |
| 5097 |
const size_t nFaceJPoints = facePoints.size(cellFacesJ); |
| 5098 |
for(size_t k = 0; k < nFaceJPoints; k++) |
| 707 |
{ |
5099 |
{ |
| 708 |
if(cellPoints[l] == this->FacePoints->value[ |
5100 |
const int faceJPointK = faceJPoints[k]; |
| 709 |
this->FacesOfCell->value[i][j].faceIndex][k]) |
5101 |
bool foundDup = false; |
|
|
5102 |
for(int l = 0; l < nPoints; l++) |
| 5103 |
{ |
| 5104 |
if(cellPoints->GetId(l) == faceJPointK) |
| 5105 |
{ |
| 5106 |
foundDup = true; |
| 5107 |
break; // look no more |
| 5108 |
} |
| 5109 |
} |
| 5110 |
if(!foundDup) |
| 710 |
{ |
5111 |
{ |
| 711 |
foundDup = true; |
5112 |
if(nPoints >= maxNPoints) |
|
|
5113 |
{ |
| 5114 |
vtkErrorMacro(<< "Too large polyhedron at cellId = " << cellId); |
| 5115 |
return; |
| 5116 |
} |
| 5117 |
cellPoints->SetId(nPoints++, faceJPointK); |
| 712 |
} |
5118 |
} |
| 713 |
} |
5119 |
} |
| 714 |
if(!foundDup) |
|
|
| 715 |
{ |
| 716 |
cellPoints.push_back(this->FacePoints->value[ |
| 717 |
this->FacesOfCell->value[i][j].faceIndex][k]); |
| 718 |
foundDup = false; |
| 719 |
} |
| 720 |
} |
5120 |
} |
| 721 |
} |
|
|
| 722 |
|
5121 |
|
| 723 |
//create the poly cell and insert it into the mesh |
5122 |
// create the poly cell and insert it into the mesh |
| 724 |
vtkConvexPointSet * poly = vtkConvexPointSet::New(); |
5123 |
internalMesh->InsertNextCell(VTK_CONVEX_POINT_SET, nPoints, |
| 725 |
poly->GetPointIds()->SetNumberOfIds(cellPoints.size()); |
5124 |
cellPoints->GetPointer(0)); |
| 726 |
for(pCount = 0; pCount < (int)cellPoints.size(); pCount++) |
|
|
| 727 |
{ |
| 728 |
poly->GetPointIds()->SetId(pCount, cellPoints[pCount]); |
| 729 |
} |
5125 |
} |
| 730 |
internalMesh->InsertNextCell(poly->GetCellType(), |
|
|
| 731 |
poly->GetPointIds()); |
| 732 |
cellPoints.clear(); |
| 733 |
firstFace.clear(); |
| 734 |
poly->Delete(); |
| 735 |
} |
5126 |
} |
| 736 |
} |
5127 |
} |
| 737 |
|
5128 |
cellPoints->Delete(); |
| 738 |
//set the internal mesh points |
|
|
| 739 |
internalMesh->SetPoints(Points); |
| 740 |
vtkDebugMacro(<<"Internal mesh made"); |
| 741 |
return internalMesh; |
| 742 |
} |
5129 |
} |
| 743 |
|
5130 |
|
| 744 |
// **************************************************************************** |
5131 |
//----------------------------------------------------------------------------- |
| 745 |
// Method: vtkOpenFOAMReader::ControlDictDataParser |
5132 |
void vtkOpenFOAMReader::SetDataObjectName(vtkDataObject *dataset, |
| 746 |
// |
5133 |
const char *name) |
| 747 |
// Purpose: |
|
|
| 748 |
// parse out double values for controlDict entries |
| 749 |
// utility function |
| 750 |
// |
| 751 |
// **************************************************************************** |
| 752 |
double vtkOpenFOAMReader::ControlDictDataParser(const char * lineIn) |
| 753 |
{ |
5134 |
{ |
| 754 |
double value; |
5135 |
vtkCharArray* nmArray = vtkCharArray::New(); |
| 755 |
vtkstd::string line(lineIn); |
5136 |
nmArray->SetName("Name"); |
| 756 |
line.erase(line.begin()+line.find(";")); |
5137 |
const size_t len = strlen(name); |
| 757 |
vtkstd::string token; |
5138 |
nmArray->SetNumberOfTuples(static_cast<vtkIdType>(len)+1); |
| 758 |
vtksys_ios::stringstream tokenizer(line); |
5139 |
char* copy = nmArray->GetPointer(0); |
| 759 |
|
5140 |
memcpy(copy, name, len); |
| 760 |
//parse to the final entry - double |
5141 |
copy[len] = '\0'; |
| 761 |
//while(tokenizer>>token); |
5142 |
dataset->GetFieldData()->AddArray(nmArray); |
| 762 |
while(!tokenizer.eof()) |
5143 |
nmArray->Delete(); |
| 763 |
{ |
|
|
| 764 |
tokenizer >> token; |
| 765 |
} |
| 766 |
|
| 767 |
vtksys_ios::stringstream conversion(token); |
| 768 |
conversion >> value; |
| 769 |
return value; |
| 770 |
} |
5144 |
} |
| 771 |
|
5145 |
|
| 772 |
// **************************************************************************** |
5146 |
#if PARAVIEW_VERSION_MAJOR >= 3 && PARAVIEW_VERSION_MINOR >= 3 |
| 773 |
// Method: vtkOpenFOAMReader::ReadControlDict |
5147 |
//----------------------------------------------------------------------------- |
| 774 |
// |
5148 |
void vtkOpenFOAMReader::SetBlockName(vtkMultiBlockDataSet *blocks, |
| 775 |
// Pupose: |
5149 |
unsigned int blockI, const char *name) |
| 776 |
// reads the controlDict File |
|
|
| 777 |
// gather the necessary information to create a path to the data |
| 778 |
// |
| 779 |
// **************************************************************************** |
| 780 |
void vtkOpenFOAMReader::ReadControlDict () |
| 781 |
{ |
5150 |
{ |
| 782 |
vtkDebugMacro(<<"Read controlDict"); |
5151 |
blocks->GetMetaData(blockI)->Set(vtkCompositeDataSet::NAME(), name); |
| 783 |
//create variables |
|
|
| 784 |
vtkstd::string temp; |
| 785 |
double startTime; |
| 786 |
double endTime; |
| 787 |
double deltaT; |
| 788 |
double writeInterval; |
| 789 |
double timeStepIncrement; |
| 790 |
vtkstd::string writeControl; |
| 791 |
vtkstd::string timeFormat; |
| 792 |
stdString* tempStringStruct; |
| 793 |
|
| 794 |
ifstream * input = new ifstream(this->Path->value.c_str(), ios::in VTK_IOS_NOCREATE); |
| 795 |
|
| 796 |
//create the path to the data directory |
| 797 |
this->PathPrefix->value = this->Path->value; |
| 798 |
this->PathPrefix->value.erase(this->PathPrefix->value.begin()+ |
| 799 |
this->PathPrefix->value.find("system"),this->PathPrefix->value.end()); |
| 800 |
vtkDebugMacro(<<"Path: "<<this->PathPrefix->value.c_str()); |
| 801 |
|
| 802 |
//find Start Time |
| 803 |
tempStringStruct = this->GetLine(input); |
| 804 |
temp = tempStringStruct->value; |
| 805 |
delete tempStringStruct; |
| 806 |
|
| 807 |
//while(!(temp.compare(0,8,"startTime",0,8) == 0)) |
| 808 |
while (strcmp(temp.substr(0,9).c_str(), "startTime")) |
| 809 |
{ |
| 810 |
tempStringStruct = this->GetLine(input); |
| 811 |
temp = tempStringStruct->value; |
| 812 |
delete tempStringStruct; |
| 813 |
} |
| 814 |
startTime = this->ControlDictDataParser(temp.c_str()); |
| 815 |
vtkDebugMacro(<<"Start time: "<<startTime); |
| 816 |
|
| 817 |
//find End Time |
| 818 |
//while(!(temp.compare(0,6,"endTime",0,6) == 0)) |
| 819 |
while (strcmp(temp.substr(0,7).c_str(), "endTime")) |
| 820 |
{ |
| 821 |
tempStringStruct = this->GetLine(input); |
| 822 |
temp = tempStringStruct->value; |
| 823 |
delete tempStringStruct; |
| 824 |
} |
| 825 |
endTime = this->ControlDictDataParser(temp.c_str()); |
| 826 |
vtkDebugMacro(<<"End time: "<<endTime); |
| 827 |
|
| 828 |
//find Delta T |
| 829 |
//while(!(temp.compare(0,5,"deltaT",0,5) == 0)) |
| 830 |
while (strcmp(temp.substr(0,6).c_str(), "deltaT")) |
| 831 |
{ |
| 832 |
tempStringStruct = this->GetLine(input); |
| 833 |
temp = tempStringStruct->value; |
| 834 |
delete tempStringStruct; |
| 835 |
} |
| 836 |
deltaT = this->ControlDictDataParser(temp.c_str()); |
| 837 |
vtkDebugMacro(<<"deltaT: "<<deltaT); |
| 838 |
|
| 839 |
//find write control |
| 840 |
//while(!(temp.compare(0,11,"writeControl",0,11) == 0)) |
| 841 |
while (strcmp(temp.substr(0,12).c_str(), "writeControl")) |
| 842 |
{ |
| 843 |
tempStringStruct = this->GetLine(input); |
| 844 |
temp = tempStringStruct->value; |
| 845 |
delete tempStringStruct; |
| 846 |
} |
| 847 |
|
| 848 |
temp.erase(temp.begin()+temp.find(";")); |
| 849 |
vtkstd::string token; |
| 850 |
vtksys_ios::stringstream tokenizer(temp); |
| 851 |
|
| 852 |
//while(tokenizer >> token); |
| 853 |
while(!tokenizer.eof()) |
| 854 |
{ |
| 855 |
tokenizer >> token; |
| 856 |
} |
| 857 |
writeControl = token; |
| 858 |
vtkDebugMacro(<<"Write control: "<<writeControl.c_str()); |
| 859 |
|
| 860 |
//find write interval |
| 861 |
//while(!(temp.compare(0,12,"writeInterval",0,12) == 0)) |
| 862 |
while (strcmp(temp.substr(0,13).c_str(), "writeInterval")) |
| 863 |
{ |
| 864 |
tempStringStruct = this->GetLine(input); |
| 865 |
temp = tempStringStruct->value; |
| 866 |
delete tempStringStruct; |
| 867 |
} |
| 868 |
writeInterval = this->ControlDictDataParser(temp.c_str()); |
| 869 |
vtkDebugMacro(<<"Write interval: "<<writeInterval); |
| 870 |
|
| 871 |
//calculate the time step increment based on type of run |
| 872 |
//if(writeControl.compare(0,7,"timeStep",0,7) == 0) |
| 873 |
if(!strcmp(writeControl.substr(0,8).c_str(), "timeStep")) |
| 874 |
{ |
| 875 |
vtkDebugMacro(<<"Time step type data"); |
| 876 |
timeStepIncrement = writeInterval * deltaT; |
| 877 |
} |
| 878 |
else |
| 879 |
{ |
| 880 |
vtkDebugMacro(<<"Run time type data"); |
| 881 |
timeStepIncrement = writeInterval; |
| 882 |
} |
| 883 |
|
| 884 |
//find time format |
| 885 |
while(temp.find("timeFormat") == vtkstd::string::npos) |
| 886 |
{ |
| 887 |
tempStringStruct = this->GetLine(input); |
| 888 |
temp = tempStringStruct->value; |
| 889 |
delete tempStringStruct; |
| 890 |
} |
| 891 |
timeFormat = temp; |
| 892 |
|
| 893 |
//calculate how many timesteps there should be |
| 894 |
float tempResult = ((endTime-startTime)/timeStepIncrement); |
| 895 |
int tempNumTimeSteps = (int)(tempResult+0.5)+1; //+0.1 to round up |
| 896 |
//make sure time step dir exists |
| 897 |
vtkstd::vector< double > tempSteps; |
| 898 |
vtkDirectory * test = vtkDirectory::New(); |
| 899 |
vtksys_ios::stringstream parser; |
| 900 |
double tempStep; |
| 901 |
for(int i = 0; i < tempNumTimeSteps; i++) |
| 902 |
{ |
| 903 |
tempStep = i*timeStepIncrement + startTime; |
| 904 |
parser.clear(); |
| 905 |
if(timeFormat.find("general") != vtkstd::string::npos) |
| 906 |
{ |
| 907 |
parser << tempStep; |
| 908 |
} |
| 909 |
else |
| 910 |
{ |
| 911 |
parser << ios::scientific <<tempStep; |
| 912 |
} |
| 913 |
if(test->Open((this->PathPrefix->value+parser.str().c_str()).c_str())) |
| 914 |
{ |
| 915 |
tempSteps.push_back(tempStep); |
| 916 |
} |
| 917 |
} |
| 918 |
test->Delete(); |
| 919 |
|
| 920 |
//Add the time steps that actually exist to steps |
| 921 |
//allows the run to be stopped short of controlDict spec |
| 922 |
//allows for removal of timesteps |
| 923 |
this->NumberOfTimeSteps = static_cast<int>(tempSteps.size()); |
| 924 |
this->Steps = new double[this->NumberOfTimeSteps]; |
| 925 |
for(int i = 0; i < this->NumberOfTimeSteps; i++) |
| 926 |
{ |
| 927 |
this->Steps[i] =tempSteps[i]; |
| 928 |
} |
| 929 |
|
| 930 |
input->close(); |
| 931 |
delete input; |
| 932 |
vtkDebugMacro(<<"controlDict read"); |
| 933 |
return; |
| 934 |
} |
5152 |
} |
| 935 |
|
5153 |
|
| 936 |
// **************************************************************************** |
5154 |
//----------------------------------------------------------------------------- |
| 937 |
// Method: vtkOpenFOAMReader::GetPoints |
5155 |
void vtkOpenFOAMReader::SetBlockName(vtkMultiBlockDataSet *blocks, |
| 938 |
// |
5156 |
unsigned int blockI, vtkDataObject *dataset) |
| 939 |
// Purpose: |
|
|
| 940 |
// read the points file into a vtkPoints |
| 941 |
// |
| 942 |
// **************************************************************************** |
| 943 |
void vtkOpenFOAMReader::GetPoints (int timeState) |
| 944 |
{ |
5157 |
{ |
| 945 |
//path to points file |
5158 |
vtkCharArray *blockNameArray = vtkCharArray::SafeDownCast(dataset |
| 946 |
vtkstd::string pointPath = this->PathPrefix->value + |
5159 |
->GetFieldData()->GetArray("Name")); |
| 947 |
this->PolyMeshPointsDir->value[timeState] + |
5160 |
this->SetBlockName(blocks, blockI, blockNameArray->GetPointer(0)); |
| 948 |
"/polyMesh/points"; |
|
|
| 949 |
vtkDebugMacro(<<"Read points file: "<<pointPath.c_str()); |
| 950 |
|
| 951 |
vtkstd::string temp; |
| 952 |
bool binaryWriteFormat; |
| 953 |
stdString* tempStringStruct; |
| 954 |
ifstream * input = new ifstream(pointPath.c_str(), ios::in VTK_IOS_NOCREATE); |
| 955 |
//make sure file exists |
| 956 |
if(input->fail()) |
| 957 |
{ |
| 958 |
input->close(); |
| 959 |
delete input; |
| 960 |
return; |
| 961 |
} |
| 962 |
|
| 963 |
//determine if file is binary or ascii |
| 964 |
while(temp.find("format") == vtkstd::string::npos) |
| 965 |
{ |
| 966 |
tempStringStruct = this->GetLine(input); |
| 967 |
temp = tempStringStruct->value; |
| 968 |
delete tempStringStruct; |
| 969 |
} |
| 970 |
input->close(); |
| 971 |
|
| 972 |
//reopen file in correct format |
| 973 |
if(temp.find("binary") != vtkstd::string::npos) |
| 974 |
{ |
| 975 |
#ifdef _WIN32 |
| 976 |
input->open(pointPath.c_str(), ios::binary | ios::in VTK_IOS_NOCREATE); |
| 977 |
#else |
| 978 |
input->open(pointPath.c_str(), ios::in VTK_IOS_NOCREATE); |
| 979 |
#endif |
| 980 |
binaryWriteFormat = true; |
| 981 |
} |
| 982 |
else |
| 983 |
{ |
| 984 |
input->open(pointPath.c_str(),ios::in); |
| 985 |
binaryWriteFormat = false; |
| 986 |
} |
| 987 |
|
| 988 |
double x,y,z; |
| 989 |
vtksys_ios::stringstream tokenizer; |
| 990 |
|
| 991 |
//instantiate the points class |
| 992 |
this->Points->Reset(); |
| 993 |
|
| 994 |
//find end of header |
| 995 |
//while(temp.compare(0,4, "// *", 0, 4) != 0) |
| 996 |
while (strcmp(temp.substr(0,4).c_str(), "// *")) |
| 997 |
{ |
| 998 |
tempStringStruct = this->GetLine(input); |
| 999 |
temp = tempStringStruct->value; |
| 1000 |
delete tempStringStruct; |
| 1001 |
} |
| 1002 |
|
| 1003 |
//find number of points |
| 1004 |
tempStringStruct = this->GetLine(input); |
| 1005 |
temp = tempStringStruct->value; |
| 1006 |
delete tempStringStruct; |
| 1007 |
while(temp.empty()) |
| 1008 |
{ |
| 1009 |
tempStringStruct = this->GetLine(input); |
| 1010 |
temp = tempStringStruct->value; |
| 1011 |
delete tempStringStruct; |
| 1012 |
} |
| 1013 |
|
| 1014 |
//read number of points |
| 1015 |
tokenizer << temp; |
| 1016 |
tokenizer >> NumPoints; |
| 1017 |
//binary data |
| 1018 |
if(binaryWriteFormat) |
| 1019 |
{ |
| 1020 |
input->get(); //parenthesis |
| 1021 |
for(int i = 0; i < NumPoints; i++) |
| 1022 |
{ |
| 1023 |
input->read((char *)&x,sizeof(double)); |
| 1024 |
input->read((char *)&y,sizeof(double)); |
| 1025 |
input->read((char *)&z,sizeof(double)); |
| 1026 |
this->Points->InsertPoint(i,x,y,z); |
| 1027 |
} |
| 1028 |
} |
| 1029 |
|
| 1030 |
//ascii data |
| 1031 |
else |
| 1032 |
{ |
| 1033 |
tempStringStruct = this->GetLine(input); |
| 1034 |
temp = tempStringStruct->value; |
| 1035 |
delete tempStringStruct; |
| 1036 |
for(int i = 0; i < this->NumPoints; i++) |
| 1037 |
{ |
| 1038 |
tempStringStruct = this->GetLine(input); |
| 1039 |
temp = tempStringStruct->value; |
| 1040 |
delete tempStringStruct; |
| 1041 |
temp.erase(temp.begin()+temp.find("(")); |
| 1042 |
temp.erase(temp.begin()+temp.find(")")); |
| 1043 |
tokenizer.clear(); |
| 1044 |
tokenizer << temp; |
| 1045 |
tokenizer >> x; |
| 1046 |
tokenizer >> y; |
| 1047 |
tokenizer >> z; |
| 1048 |
this->Points->InsertPoint(i,x,y,z); |
| 1049 |
} |
| 1050 |
} |
| 1051 |
|
| 1052 |
input->close(); |
| 1053 |
delete input; |
| 1054 |
vtkDebugMacro(<<"Point file read"); |
| 1055 |
return; |
| 1056 |
} |
5161 |
} |
| 1057 |
|
|
|
| 1058 |
// **************************************************************************** |
| 1059 |
// Method: vtkOpenFOAMReader::ReadFacesFile |
| 1060 |
// |
| 1061 |
// Purpose: |
| 1062 |
// read the faces into a vtkstd::vector |
| 1063 |
// |
| 1064 |
// **************************************************************************** |
| 1065 |
void vtkOpenFOAMReader::ReadFacesFile (const char * facePathIn) |
| 1066 |
{ |
| 1067 |
vtkstd::string facePath(facePathIn); |
| 1068 |
vtkDebugMacro(<<"Read faces file: "<<facePath.c_str()); |
| 1069 |
vtkstd::string temp; |
| 1070 |
stdString* tempStringStruct; |
| 1071 |
bool binaryWriteFormat; |
| 1072 |
ifstream * input = new ifstream(facePath.c_str(), ios::in VTK_IOS_NOCREATE); |
| 1073 |
//make sure file exists |
| 1074 |
if(input->fail()) |
| 1075 |
{ |
| 1076 |
input->close(); |
| 1077 |
delete input; |
| 1078 |
return; |
| 1079 |
} |
| 1080 |
|
| 1081 |
//determine if file is binary or ascii |
| 1082 |
while(temp.find("format") == vtkstd::string::npos) |
| 1083 |
{ |
| 1084 |
tempStringStruct = this->GetLine(input); |
| 1085 |
temp = tempStringStruct->value; |
| 1086 |
delete tempStringStruct; |
| 1087 |
} |
| 1088 |
input->close(); |
| 1089 |
|
| 1090 |
//reopen file in correct format |
| 1091 |
if(temp.find("binary") != vtkstd::string::npos) |
| 1092 |
{ |
| 1093 |
#ifdef _WIN32 |
| 1094 |
input->open(facePath.c_str(), ios::binary | ios::in VTK_IOS_NOCREATE); |
| 1095 |
#else |
| 1096 |
input->open(facePath.c_str(), ios::in VTK_IOS_NOCREATE); |
| 1097 |
#endif |
5162 |
#endif |
| 1098 |
binaryWriteFormat = true; |
|
|
| 1099 |
} |
| 1100 |
else |
| 1101 |
{ |
| 1102 |
input->open(facePath.c_str(),ios::in); |
| 1103 |
binaryWriteFormat = false; |
| 1104 |
} |
| 1105 |
|
5163 |
|
| 1106 |
vtksys_ios::stringstream tokenizer; |
5164 |
//----------------------------------------------------------------------------- |
| 1107 |
size_t pos; |
5165 |
// derive cell types and create the internal mesh |
| 1108 |
int numFacePoints; |
5166 |
vtkUnstructuredGrid * vtkOpenFOAMReader::MakeInternalMesh( |
| 1109 |
this->FacePoints->value.clear(); |
5167 |
vtkIntArray *cellFacesList, vtkIntArray *cellFacesIndices, |
|
|
5168 |
const intVectorVector *facesPoints, vtkFloatArray *pointArray) |
| 5169 |
{ |
| 5170 |
vtkDebugMacro(<<"Make internal mesh"); |
| 1110 |
|
5171 |
|
| 1111 |
//find end of header |
5172 |
// Create Mesh |
| 1112 |
//while(temp.compare(0,4, "// *", 0, 4) != 0) |
5173 |
vtkUnstructuredGrid* internalMesh = vtkUnstructuredGrid::New(); |
| 1113 |
while (strcmp(temp.substr(0,4).c_str(), "// *")) |
5174 |
internalMesh->Allocate(this->NumCells); |
| 1114 |
{ |
|
|
| 1115 |
tempStringStruct = this->GetLine(input); |
| 1116 |
temp = tempStringStruct->value; |
| 1117 |
delete tempStringStruct; |
| 1118 |
} |
| 1119 |
|
5175 |
|
| 1120 |
//find number of faces |
5176 |
if(this->DecomposePolyhedra) |
| 1121 |
tempStringStruct = this->GetLine(input); |
|
|
| 1122 |
temp = tempStringStruct->value; |
| 1123 |
delete tempStringStruct; |
| 1124 |
while(temp.empty()) |
| 1125 |
{ |
5177 |
{ |
| 1126 |
tempStringStruct = this->GetLine(input); |
5178 |
// for polyhedral decomposition |
| 1127 |
temp = tempStringStruct->value; |
5179 |
this->AdditionalCellIds = vtkIntArray::New(); |
| 1128 |
delete tempStringStruct; |
5180 |
this->AdditionalCellPoints = new intArrayVector; |
| 1129 |
} |
|
|
| 1130 |
|
| 1131 |
//read number of faces |
| 1132 |
tokenizer << temp; |
| 1133 |
tokenizer >> this->NumFaces; |
| 1134 |
this->FacePoints->value.resize(this->NumFaces); |
| 1135 |
|
5181 |
|
| 1136 |
tempStringStruct = this->GetLine(input); |
5182 |
vtkIdTypeArray *additionalCells = vtkIdTypeArray::New(); |
| 1137 |
temp = tempStringStruct->value; |
5183 |
additionalCells->SetNumberOfComponents(5); // accommodates tetra or pyramid |
| 1138 |
delete tempStringStruct;//THROW OUT "(" |
|
|
| 1139 |
|
5184 |
|
| 1140 |
//binary data |
5185 |
this->InsertCellsToGrid(internalMesh, cellFacesList, cellFacesIndices, |
| 1141 |
if(binaryWriteFormat) |
5186 |
facesPoints, pointArray, additionalCells, NULL); |
| 1142 |
{ |
|
|
| 1143 |
//char paren; |
| 1144 |
int tempPoint; |
| 1145 |
for(int i = 0; i < NumFaces; i++) |
| 1146 |
{ |
| 1147 |
tempStringStruct = this->GetLine(input); |
| 1148 |
temp = tempStringStruct->value; |
| 1149 |
delete tempStringStruct;//THROW OUT blankline |
| 1150 |
|
5187 |
|
| 1151 |
tempStringStruct = this->GetLine(input); |
5188 |
// for polyhedral decomposition |
| 1152 |
temp = tempStringStruct->value; |
5189 |
pointArray->Squeeze(); |
| 1153 |
delete tempStringStruct; //grab point count |
5190 |
this->AdditionalCellIds->Squeeze(); |
|
|
5191 |
additionalCells->Squeeze(); |
| 1154 |
|
5192 |
|
| 1155 |
tokenizer.clear(); |
5193 |
// insert decomposed cells into mesh |
| 1156 |
tokenizer << temp; |
5194 |
const int nComponents = additionalCells->GetNumberOfComponents(); |
| 1157 |
tokenizer >> numFacePoints; |
5195 |
const int nAdditionalCells = additionalCells->GetNumberOfTuples(); |
| 1158 |
this->FacePoints->value[i].resize(numFacePoints); |
5196 |
for(int i = 0; i < nAdditionalCells; i++) |
| 1159 |
//paren = input->get(); //grab ( |
5197 |
{ |
| 1160 |
input->get(); //grab ( |
5198 |
if(additionalCells->GetComponent(i, 4) == -1) |
| 1161 |
for(int j = 0; j < numFacePoints; j++) |
|
|
| 1162 |
{ |
5199 |
{ |
| 1163 |
input->read((char *) &tempPoint, sizeof(int)); |
5200 |
internalMesh->InsertNextCell(VTK_TETRA, 4, |
| 1164 |
this->FacePoints->value[i][j] = tempPoint; |
5201 |
additionalCells->GetPointer(i * nComponents)); |
| 1165 |
} |
5202 |
} |
| 1166 |
tempStringStruct = this->GetLine(input); |
5203 |
else |
| 1167 |
temp = tempStringStruct->value; |
|
|
| 1168 |
delete tempStringStruct; //throw out ) and rest of line |
| 1169 |
} |
| 1170 |
} |
| 1171 |
|
| 1172 |
//ascii data |
| 1173 |
else |
| 1174 |
{ |
| 1175 |
//create vtkstd::vector of points in each face |
| 1176 |
for(int i = 0; i < this->NumFaces; i++) |
| 1177 |
{ |
| 1178 |
tempStringStruct = this->GetLine(input); |
| 1179 |
temp = tempStringStruct->value; |
| 1180 |
delete tempStringStruct; |
| 1181 |
|
| 1182 |
pos = temp.find("("); |
| 1183 |
vtksys_ios::stringstream ascTokenizer; |
| 1184 |
ascTokenizer << temp.substr(0, pos); |
| 1185 |
temp.erase(0, pos+1); |
| 1186 |
ascTokenizer >> numFacePoints; |
| 1187 |
this->FacePoints->value[i].resize(numFacePoints); |
| 1188 |
for(int j = 0; j < numFacePoints; j++) |
| 1189 |
{ |
5204 |
{ |
| 1190 |
pos = temp.find(" "); |
5205 |
internalMesh->InsertNextCell(VTK_PYRAMID, 5, |
| 1191 |
vtksys_ios::stringstream lineTokenizer; |
5206 |
additionalCells->GetPointer(i * nComponents)); |
| 1192 |
lineTokenizer << temp.substr(0, pos); |
|
|
| 1193 |
temp.erase(0, pos+1); |
| 1194 |
lineTokenizer >> this->FacePoints->value[i][j]; |
| 1195 |
} |
5207 |
} |
| 1196 |
} |
5208 |
} |
| 1197 |
} |
5209 |
internalMesh->Squeeze(); |
| 1198 |
|
5210 |
additionalCells->Delete(); |
| 1199 |
input->close(); |
|
|
| 1200 |
delete input; |
| 1201 |
vtkDebugMacro(<<"Faces read"); |
| 1202 |
return; |
| 1203 |
} |
| 1204 |
|
| 1205 |
// **************************************************************************** |
| 1206 |
// Method: vtkOpenFOAMReader::ReadOwnerFile |
| 1207 |
// |
| 1208 |
// Purpose: |
| 1209 |
// read the owner file into a vtkstd::vector |
| 1210 |
// |
| 1211 |
// **************************************************************************** |
| 1212 |
void vtkOpenFOAMReader::ReadOwnerFile(const char * ownerPathIn) |
| 1213 |
{ |
| 1214 |
vtkstd::string ownerPath(ownerPathIn); |
| 1215 |
vtkDebugMacro(<<"Read owner file: "<<ownerPath.c_str()); |
| 1216 |
vtkstd::string temp; |
| 1217 |
stdString* tempStringStruct; |
| 1218 |
bool binaryWriteFormat; |
| 1219 |
ifstream * input = new ifstream(ownerPath.c_str(), ios::in VTK_IOS_NOCREATE); |
| 1220 |
//make sure file exists |
| 1221 |
if(input->fail()) |
| 1222 |
{ |
| 1223 |
input->close(); |
| 1224 |
delete input; |
| 1225 |
return; |
| 1226 |
} |
| 1227 |
|
| 1228 |
//determine if file is binary or ascii |
| 1229 |
while(temp.find("format") == vtkstd::string::npos) |
| 1230 |
{ |
| 1231 |
tempStringStruct = this->GetLine(input); |
| 1232 |
temp = tempStringStruct->value; |
| 1233 |
delete tempStringStruct; |
| 1234 |
} |
| 1235 |
input->close(); |
| 1236 |
|
| 1237 |
//reopen file in correct format |
| 1238 |
if(temp.find("binary") != vtkstd::string::npos) |
| 1239 |
{ |
| 1240 |
#ifdef _WIN32 |
| 1241 |
input->open(ownerPath.c_str(), ios::binary | ios::in VTK_IOS_NOCREATE); |
| 1242 |
#else |
| 1243 |
input->open(ownerPath.c_str(), ios::in VTK_IOS_NOCREATE); |
| 1244 |
#endif |
| 1245 |
binaryWriteFormat = true; |
| 1246 |
} |
5211 |
} |
| 1247 |
else |
5212 |
else |
| 1248 |
{ |
5213 |
{ |
| 1249 |
input->open(ownerPath.c_str(),ios::in); |
5214 |
this->InsertCellsToGrid(internalMesh, cellFacesList, cellFacesIndices, |
| 1250 |
binaryWriteFormat = false; |
5215 |
facesPoints, pointArray, NULL, NULL); |
| 1251 |
} |
5216 |
} |
| 1252 |
|
5217 |
|
| 1253 |
vtkstd::string numFacesStr; |
5218 |
// set the internal mesh points |
| 1254 |
int faceValue; |
5219 |
vtkPoints *points = vtkPoints::New(); |
| 1255 |
|
5220 |
points->SetData(pointArray); |
| 1256 |
this->FaceOwner = vtkIntArray::New(); |
5221 |
internalMesh->SetPoints(points); |
|
|
5222 |
points->Delete(); |
| 5223 |
this->SetDataObjectName(internalMesh, "Internal Mesh"); |
| 1257 |
|
5224 |
|
| 1258 |
vtksys_ios::stringstream tokenizer; |
5225 |
vtkDebugMacro(<<"Internal mesh made"); |
| 1259 |
tokenizer << this->NumFaces; |
5226 |
return internalMesh; |
| 1260 |
tokenizer >> numFacesStr; |
5227 |
} |
| 1261 |
//find end of header & number of faces |
|
|
| 1262 |
//while(temp.compare(0,numFacesStr.size(),numFacesStr, |
| 1263 |
//0,numFacesStr.size())!=0) |
| 1264 |
while(strcmp(temp.substr(0,numFacesStr.size()).c_str(), numFacesStr.c_str())) |
| 1265 |
{ |
| 1266 |
tempStringStruct = this->GetLine(input); |
| 1267 |
temp = tempStringStruct->value; |
| 1268 |
delete tempStringStruct; |
| 1269 |
} |
| 1270 |
|
5228 |
|
| 1271 |
this->FaceOwner->SetNumberOfValues(this->NumFaces); |
5229 |
//----------------------------------------------------------------------------- |
|
|
5230 |
// insert faces to grid |
| 5231 |
void vtkOpenFOAMReader::InsertFacesToGrid(vtkUnstructuredGrid *boundaryMesh, |
| 5232 |
const intVectorVector *facesPoints, int startFace, int endFace, |
| 5233 |
vtkIntArray *boundaryPointMap, vtkIdList *facePointsVtkId, |
| 5234 |
vtkIntArray *labels, bool isLookupValue) |
| 5235 |
{ |
| 5236 |
vtkUnstructuredGrid &bm = *boundaryMesh; |
| 1272 |
|
5237 |
|
| 1273 |
//binary data |
5238 |
for(int j = startFace; j < endFace; j++) |
| 1274 |
if(binaryWriteFormat) |
|
|
| 1275 |
{ |
5239 |
{ |
| 1276 |
input->get(); //parenthesis |
5240 |
int faceId; |
| 1277 |
for(int i = 0; i < NumFaces; i++) |
5241 |
if(labels == NULL) |
| 1278 |
{ |
5242 |
{ |
| 1279 |
input->read((char *) &faceValue, sizeof(int)); |
5243 |
faceId = j; |
| 1280 |
this->FaceOwner->SetValue(i, faceValue); |
|
|
| 1281 |
} |
5244 |
} |
| 1282 |
} |
5245 |
else |
| 1283 |
|
|
|
| 1284 |
//ascii data |
| 1285 |
else |
| 1286 |
{ |
| 1287 |
tempStringStruct = this->GetLine(input); |
| 1288 |
temp = tempStringStruct->value; |
| 1289 |
delete tempStringStruct; |
| 1290 |
|
| 1291 |
//read face owners into int array |
| 1292 |
for(int i = 0; i < this->NumFaces; i++) |
| 1293 |
{ |
5246 |
{ |
| 1294 |
tempStringStruct = this->GetLine(input); |
5247 |
faceId = labels->GetValue(j); |
| 1295 |
temp = tempStringStruct->value; |
5248 |
if(faceId >= this->FaceOwner->GetNumberOfTuples()) |
| 1296 |
delete tempStringStruct; |
5249 |
{ |
| 1297 |
|
5250 |
vtkWarningMacro(<<"faceLabels id " << faceId |
| 1298 |
tokenizer.clear(); |
5251 |
<< " exceeds the number of faces " |
| 1299 |
tokenizer << temp; |
5252 |
<< this->FaceOwner->GetNumberOfTuples()); |
| 1300 |
tokenizer >> faceValue; |
5253 |
bm.InsertNextCell(VTK_EMPTY_CELL, 0, facePointsVtkId->GetPointer(0)); |
| 1301 |
this->FaceOwner->SetValue(i, faceValue); |
5254 |
continue; |
|
|
5255 |
} |
| 1302 |
} |
5256 |
} |
| 1303 |
} |
5257 |
const int *facePoints = facesPoints->operator[](faceId); |
|
|
5258 |
size_t nFacePoints = facesPoints->size(faceId); |
| 1304 |
|
5259 |
|
| 1305 |
//find the number of cells |
5260 |
if(isLookupValue) |
| 1306 |
double * range; |
5261 |
{ |
| 1307 |
range = this->FaceOwner->GetRange(); |
5262 |
for(size_t k = 0; k < nFacePoints; k++) |
| 1308 |
this->NumCells = (int)range[1]+1; |
5263 |
{ |
|
|
5264 |
facePointsVtkId->SetId(k, boundaryPointMap->LookupValue(facePoints[k])); |
| 5265 |
} |
| 5266 |
} |
| 5267 |
else |
| 5268 |
{ |
| 5269 |
if(boundaryPointMap) |
| 5270 |
{ |
| 5271 |
for(size_t k = 0; k < nFacePoints; k++) |
| 5272 |
{ |
| 5273 |
facePointsVtkId->SetId(k, boundaryPointMap->GetValue(facePoints[k])); |
| 5274 |
} |
| 5275 |
} |
| 5276 |
else |
| 5277 |
{ |
| 5278 |
for(size_t k = 0; k < nFacePoints; k++) |
| 5279 |
{ |
| 5280 |
facePointsVtkId->SetId(k, facePoints[k]); |
| 5281 |
} |
| 5282 |
} |
| 5283 |
} |
| 1309 |
|
5284 |
|
| 1310 |
//add the face number to the correct cell |
5285 |
// triangle |
| 1311 |
//according to owner |
5286 |
if(nFacePoints == 3) |
| 1312 |
this->FacesOwnerCell->value.resize(this->NumCells); |
5287 |
{ |
| 1313 |
int tempCellId; |
5288 |
bm.InsertNextCell(VTK_TRIANGLE, 3, facePointsVtkId->GetPointer(0)); |
| 1314 |
for(int j = 0; j < this->NumFaces; j++) |
5289 |
} |
| 1315 |
{ |
5290 |
// quad |
| 1316 |
tempCellId = this->FaceOwner->GetValue(j); |
5291 |
else if(nFacePoints == 4) |
| 1317 |
if(tempCellId != -1) |
5292 |
{ |
|
|
5293 |
bm.InsertNextCell(VTK_QUAD, 4, facePointsVtkId->GetPointer(0)); |
| 5294 |
} |
| 5295 |
// polygon |
| 5296 |
else |
| 1318 |
{ |
5297 |
{ |
| 1319 |
this->FacesOwnerCell->value[tempCellId].push_back(j); |
5298 |
bm.InsertNextCell(VTK_POLYGON, nFacePoints, |
|
|
5299 |
facePointsVtkId->GetPointer(0)); |
| 1320 |
} |
5300 |
} |
| 1321 |
} |
5301 |
} |
| 1322 |
|
|
|
| 1323 |
input->close(); |
| 1324 |
delete input; |
| 1325 |
vtkDebugMacro(<<"Owner file read"); |
| 1326 |
return; |
| 1327 |
} |
5302 |
} |
| 1328 |
|
5303 |
|
| 1329 |
// **************************************************************************** |
5304 |
//----------------------------------------------------------------------------- |
| 1330 |
// Method: vtkOpenFOAMReader::ReadNeighborFile |
5305 |
// returns requested boundary meshes |
| 1331 |
// |
5306 |
unstructuredGridVector* vtkOpenFOAMReader::MakeBoundaryMesh( |
| 1332 |
// Purpose: |
5307 |
vtkFoamBoundaryDict* boundaryDictPtr, const intVectorVector *facesPoints, |
| 1333 |
// read the neighbor file into a vtkstd::vector |
5308 |
vtkFloatArray* pointArray) |
| 1334 |
// |
|
|
| 1335 |
// **************************************************************************** |
| 1336 |
void vtkOpenFOAMReader::ReadNeighborFile(const char * neighborPathIn) |
| 1337 |
{ |
5309 |
{ |
| 1338 |
vtkstd::string neighborPath(neighborPathIn); |
5310 |
vtkFoamBoundaryDict& boundaryDict = *boundaryDictPtr; |
| 1339 |
vtkDebugMacro(<<"Read neighbor file: "<<neighborPath.c_str()); |
5311 |
const int nBoundaries = boundaryDict.size(); |
| 1340 |
vtkstd::string temp; |
5312 |
unstructuredGridVector *boundaryMesh = new unstructuredGridVector; |
| 1341 |
stdString* tempStringStruct; |
|
|
| 1342 |
bool binaryWriteFormat; |
| 1343 |
ifstream * input = new ifstream(neighborPath.c_str(), ios::in VTK_IOS_NOCREATE); |
| 1344 |
//make sure file exists |
| 1345 |
if(input->fail()) |
| 1346 |
{ |
| 1347 |
input->close(); |
| 1348 |
delete input; |
| 1349 |
return; |
| 1350 |
} |
| 1351 |
|
| 1352 |
//determine if file is binary or ascii |
| 1353 |
while(temp.find("format") == vtkstd::string::npos) |
| 1354 |
{ |
| 1355 |
tempStringStruct = this->GetLine(input); |
| 1356 |
temp = tempStringStruct->value; |
| 1357 |
delete tempStringStruct; |
| 1358 |
} |
| 1359 |
input->close(); |
| 1360 |
|
5313 |
|
| 1361 |
//reopen file in correct format |
5314 |
if(this->CreateCellToPoint) |
| 1362 |
if(temp.find("binary") != vtkstd::string::npos) |
|
|
| 1363 |
{ |
| 1364 |
#ifdef _WIN32 |
| 1365 |
input->open(neighborPath.c_str(), ios::binary | ios::in VTK_IOS_NOCREATE); |
| 1366 |
#else |
| 1367 |
input->open(neighborPath.c_str(), ios::in VTK_IOS_NOCREATE); |
| 1368 |
#endif |
| 1369 |
binaryWriteFormat = true; |
| 1370 |
} |
| 1371 |
else |
| 1372 |
{ |
5315 |
{ |
| 1373 |
input->open(neighborPath.c_str(),ios::in); |
5316 |
this->AllBoundaries = vtkUnstructuredGrid::New(); |
| 1374 |
binaryWriteFormat = false; |
5317 |
this->AllBoundaries->Allocate(facesPoints->nElements() |
|
|
5318 |
- boundaryDict[0].startFace); |
| 1375 |
} |
5319 |
} |
|
|
5320 |
this->BoundaryPointMap = new intArrayVector; |
| 1376 |
|
5321 |
|
| 1377 |
vtkstd::string numFacesStr; |
5322 |
vtkIntArray *nBoundaryPointsList = vtkIntArray::New(); |
| 1378 |
int faceValue; |
5323 |
nBoundaryPointsList->SetNumberOfValues(nBoundaries); |
| 1379 |
vtkIntArray * faceNeighbor = vtkIntArray::New(); |
|
|
| 1380 |
|
5324 |
|
| 1381 |
vtksys_ios::stringstream tokenizer; |
5325 |
// count the max number of points per face and the number of points |
| 1382 |
tokenizer << this->NumFaces; |
5326 |
// (with duplicates) in mesh |
| 1383 |
tokenizer >> numFacesStr; |
5327 |
int maxNFacePoints = 0; |
| 1384 |
//find end of header & number of faces |
5328 |
for(int boundaryI = 0; boundaryI < nBoundaries; boundaryI++) |
| 1385 |
//while(temp.compare(0,numFacesStr.size(),numFacesStr,0, |
|
|
| 1386 |
//numFacesStr.size())!=0) |
| 1387 |
while (strcmp(temp.substr(0,numFacesStr.size()).c_str(), numFacesStr.c_str())) |
| 1388 |
{ |
5329 |
{ |
| 1389 |
tempStringStruct = this->GetLine(input); |
5330 |
const int startFace = boundaryDict[boundaryI].startFace; |
| 1390 |
temp = tempStringStruct->value; |
5331 |
const int endFace = startFace + boundaryDict[boundaryI].nFaces; |
| 1391 |
delete tempStringStruct; |
5332 |
int nPoints = 0; |
|
|
5333 |
for(int j = startFace; j < endFace; j++) |
| 5334 |
{ |
| 5335 |
const int nFacePoints = facesPoints->size(j); |
| 5336 |
nPoints += nFacePoints; |
| 5337 |
if(nFacePoints > maxNFacePoints) |
| 5338 |
{ |
| 5339 |
maxNFacePoints = nFacePoints; |
| 5340 |
} |
| 5341 |
} |
| 5342 |
nBoundaryPointsList->SetValue(boundaryI, nPoints); |
| 1392 |
} |
5343 |
} |
| 1393 |
|
5344 |
|
| 1394 |
//read face owners into int array |
5345 |
// aloocate array for converting int vector to vtkIdType List: |
| 1395 |
faceNeighbor->SetNumberOfValues(this->NumFaces); |
5346 |
// workaround for 64bit machines |
|
|
5347 |
vtkIdList *facePointsVtkId = vtkIdList::New(); |
| 5348 |
facePointsVtkId->SetNumberOfIds(maxNFacePoints); |
| 1396 |
|
5349 |
|
| 1397 |
//binary data |
5350 |
// create initial internal point list: set all points to -1 |
| 1398 |
if(binaryWriteFormat) |
5351 |
if(this->CreateCellToPoint) |
| 1399 |
{ |
5352 |
{ |
| 1400 |
input->get(); //parenthesis |
5353 |
this->InternalPoints = vtkIntArray::New(); |
| 1401 |
for(int i = 0; i < this->NumFaces; i++) |
5354 |
this->InternalPoints->SetNumberOfValues(this->NumPoints); |
|
|
5355 |
for(int pointI = 0; pointI < this->NumPoints; pointI++) |
| 1402 |
{ |
5356 |
{ |
| 1403 |
input->read((char *) &faceValue, sizeof(int)); |
5357 |
this->InternalPoints->SetValue(pointI, -1); |
| 1404 |
faceNeighbor->SetValue(i, faceValue); |
|
|
| 1405 |
} |
5358 |
} |
| 1406 |
} |
|
|
| 1407 |
|
5359 |
|
| 1408 |
//ascii data |
5360 |
// mark boundary points as 0 |
| 1409 |
else |
5361 |
for(int boundaryI = 0; boundaryI < nBoundaries; boundaryI++) |
| 1410 |
{ |
|
|
| 1411 |
tempStringStruct = this->GetLine(input); |
| 1412 |
temp = tempStringStruct->value; |
| 1413 |
delete tempStringStruct;//throw away ( |
| 1414 |
//read face owners into int array |
| 1415 |
for(int i = 0; i < this->NumFaces; i++) |
| 1416 |
{ |
5362 |
{ |
| 1417 |
tempStringStruct = this->GetLine(input); |
5363 |
if(boundaryDict[boundaryI].isPhysicalBoundary) |
| 1418 |
temp = tempStringStruct->value; |
5364 |
{ |
| 1419 |
delete tempStringStruct; |
5365 |
const int startFace = boundaryDict[boundaryI].startFace; |
|
|
5366 |
const int endFace = startFace + boundaryDict[boundaryI].nFaces; |
| 1420 |
|
5367 |
|
| 1421 |
tokenizer.clear(); |
5368 |
for(int j = startFace; j < endFace; j++) |
| 1422 |
tokenizer << temp; |
5369 |
{ |
| 1423 |
tokenizer >> faceValue; |
5370 |
const int *facePoints = facesPoints->operator[](j); |
| 1424 |
faceNeighbor->SetValue(i, faceValue); |
5371 |
const int nFacePoints = facesPoints->size(j); |
|
|
5372 |
for(int k = 0; k < nFacePoints; k++) |
| 5373 |
{ |
| 5374 |
this->InternalPoints->SetValue(facePoints[k], 0); |
| 5375 |
} |
| 5376 |
} |
| 5377 |
} |
| 1425 |
} |
5378 |
} |
| 1426 |
} |
5379 |
} |
| 1427 |
//No need to recalulate the Number of Cells |
|
|
| 1428 |
this->FacesNeighborCell->value.resize(this->NumCells); |
| 1429 |
|
5380 |
|
| 1430 |
//add face number to correct cell |
5381 |
// create global to AllBounaries point map |
| 1431 |
int tempCellId; |
5382 |
int nAllBoundaryPoints = 0; |
| 1432 |
for(int j = 0; j < this->NumFaces; j++) |
5383 |
if(this->CreateCellToPoint) |
| 1433 |
{ |
5384 |
{ |
| 1434 |
tempCellId = faceNeighbor->GetValue(j); |
5385 |
for(int pointI = 0; pointI < this->NumPoints; pointI++) |
| 1435 |
if(tempCellId != -1) |
|
|
| 1436 |
{ |
5386 |
{ |
| 1437 |
this->FacesNeighborCell->value[tempCellId].push_back(j); |
5387 |
if(this->InternalPoints->GetValue(pointI) == 0) |
|
|
5388 |
{ |
| 5389 |
this->InternalPoints->SetValue(pointI, nAllBoundaryPoints); |
| 5390 |
nAllBoundaryPoints++; |
| 5391 |
} |
| 1438 |
} |
5392 |
} |
| 1439 |
} |
5393 |
} |
| 1440 |
|
5394 |
|
| 1441 |
faceNeighbor->Delete(); |
5395 |
for(int boundaryI = 0; boundaryI < nBoundaries; boundaryI++) |
| 1442 |
input->close(); |
5396 |
{ |
| 1443 |
delete input; |
5397 |
const int nFaces = boundaryDict[boundaryI].nFaces; |
| 1444 |
vtkDebugMacro(<<"Neighbor file read"); |
5398 |
const int startFace = boundaryDict[boundaryI].startFace; |
| 1445 |
return; |
5399 |
const int endFace = startFace + nFaces; |
| 1446 |
} |
|
|
| 1447 |
|
5400 |
|
| 1448 |
// **************************************************************************** |
5401 |
if(this->CreateCellToPoint && boundaryDict[boundaryI].isPhysicalBoundary) |
| 1449 |
// Method: vtkOpenFOAMReader::PopulatePolyMeshDirArrays |
5402 |
{ |
| 1450 |
// |
5403 |
// add faces to AllBoundaries |
| 1451 |
// Purpose: |
5404 |
this->InsertFacesToGrid(this->AllBoundaries, facesPoints, startFace, |
| 1452 |
// create a Lookup Table containing the location of the points |
5405 |
endFace, this->InternalPoints, facePointsVtkId, NULL, false); |
| 1453 |
// and faces files for each time steps mesh |
5406 |
} |
| 1454 |
// |
|
|
| 1455 |
// **************************************************************************** |
| 1456 |
void vtkOpenFOAMReader::PopulatePolyMeshDirArrays() |
| 1457 |
{ |
| 1458 |
vtkDebugMacro(<<"Create list of points/faces file directories"); |
| 1459 |
vtksys_ios::stringstream path; |
| 1460 |
vtksys_ios::stringstream timeStep; |
| 1461 |
bool facesFound; |
| 1462 |
bool pointsFound; |
| 1463 |
bool polyMeshFound; |
| 1464 |
|
| 1465 |
//intialize size to number of timesteps |
| 1466 |
this->PolyMeshPointsDir->value.resize(this->NumberOfTimeSteps); |
| 1467 |
this->PolyMeshFacesDir->value.resize(this->NumberOfTimeSteps); |
| 1468 |
|
5407 |
|
| 1469 |
//loop through each timestep |
5408 |
// skip below if inactive |
| 1470 |
for(int i = 0; i < this->NumberOfTimeSteps; i++) |
5409 |
if(!boundaryDict[boundaryI].isActive) |
| 1471 |
{ |
5410 |
{ |
| 1472 |
polyMeshFound = false; |
5411 |
continue; |
| 1473 |
facesFound = false; |
5412 |
} |
| 1474 |
pointsFound = false; |
|
|
| 1475 |
|
5413 |
|
| 1476 |
//create the path to the timestep |
5414 |
// create the mesh |
| 1477 |
path.clear(); |
5415 |
boundaryMesh->push_back(vtkUnstructuredGrid::New()); |
| 1478 |
timeStep.clear(); |
5416 |
vtkUnstructuredGrid& bm = *boundaryMesh->back(); |
| 1479 |
timeStep << Steps[i]; |
5417 |
bm.Allocate(nFaces); |
| 1480 |
path << this->PathPrefix->value <<timeStep.str() << "/"; |
5418 |
const int nBoundaryPoints = nBoundaryPointsList->GetValue(boundaryI); |
| 1481 |
|
5419 |
|
| 1482 |
//get the number of files |
5420 |
// create global to boundary-local point map and boundary points |
| 1483 |
vtkDirectory * directory = vtkDirectory::New(); |
5421 |
vtkIntArray *boundaryPointList = vtkIntArray::New(); |
| 1484 |
directory->Open(path.str().c_str()); |
5422 |
boundaryPointList->SetNumberOfValues(nBoundaryPoints); |
| 1485 |
int numFiles = directory->GetNumberOfFiles(); |
5423 |
int pointI = 0; |
| 1486 |
//Look for polyMesh Dir |
5424 |
for(int j = startFace; j < endFace; j++) |
| 1487 |
for(int j = 0; j < numFiles; j++) |
|
|
| 1488 |
{ |
5425 |
{ |
| 1489 |
vtkstd::string tempFile(directory->GetFile(j)); |
5426 |
const int *facePoints = facesPoints->operator[](j); |
| 1490 |
if(tempFile.find("polyMesh") != vtkstd::string::npos) |
5427 |
int nFacePoints = facesPoints->size(j); |
|
|
5428 |
for(int k = 0; k < nFacePoints; k++) |
| 1491 |
{ |
5429 |
{ |
| 1492 |
polyMeshFound = true; |
5430 |
boundaryPointList->SetValue(pointI, facePoints[k]); |
| 1493 |
|
5431 |
pointI++; |
| 1494 |
path << "polyMesh/"; |
|
|
| 1495 |
|
| 1496 |
//get number of files in the polyMesh dir |
| 1497 |
vtkDirectory * polyMeshDirectory = vtkDirectory::New(); |
| 1498 |
polyMeshDirectory->Open(path.str().c_str()); |
| 1499 |
int numPolyMeshFiles = polyMeshDirectory->GetNumberOfFiles(); |
| 1500 |
//Look for points/faces files |
| 1501 |
for(int k = 0; k < numPolyMeshFiles; k++) |
| 1502 |
{ |
| 1503 |
vtkstd::string tempFile2 = vtkstd::string(polyMeshDirectory-> |
| 1504 |
GetFile(k)); |
| 1505 |
if(tempFile2.find("points") != vtkstd::string::npos) |
| 1506 |
{ |
| 1507 |
this->PolyMeshPointsDir->value[i] = timeStep.str(); |
| 1508 |
pointsFound = true; |
| 1509 |
} |
| 1510 |
else if(tempFile2.find("faces") != vtkstd::string::npos) |
| 1511 |
{ |
| 1512 |
this->PolyMeshFacesDir->value[i] = timeStep.str(); |
| 1513 |
facesFound = true; |
| 1514 |
} |
| 1515 |
} |
| 1516 |
|
| 1517 |
//if there is no points or faces found in this timestep |
| 1518 |
//set it equal to previous time step if no previous |
| 1519 |
//set it equal to "constant" dir |
| 1520 |
if(!pointsFound) |
| 1521 |
{ |
| 1522 |
if(i != 0) |
| 1523 |
{ |
| 1524 |
this->PolyMeshPointsDir->value[i] = |
| 1525 |
this->PolyMeshPointsDir->value[i-1]; |
| 1526 |
} |
| 1527 |
else |
| 1528 |
{ |
| 1529 |
this->PolyMeshPointsDir->value[i] = vtkstd::string("constant"); |
| 1530 |
} |
| 1531 |
} |
| 1532 |
if(!facesFound) |
| 1533 |
{ |
| 1534 |
if(i != 0) |
| 1535 |
{ |
| 1536 |
this->PolyMeshFacesDir->value[i] = |
| 1537 |
this->PolyMeshFacesDir->value[i-1]; |
| 1538 |
} |
| 1539 |
else |
| 1540 |
{ |
| 1541 |
this->PolyMeshFacesDir->value[i] = vtkstd::string("constant"); |
| 1542 |
} |
| 1543 |
} |
| 1544 |
|
| 1545 |
polyMeshDirectory->Delete(); |
| 1546 |
break; //found - stop looking |
| 1547 |
} |
5432 |
} |
| 1548 |
} |
5433 |
} |
| 1549 |
|
5434 |
vtkSortDataArray::Sort(boundaryPointList); |
| 1550 |
//if there is no polyMesh dir |
5435 |
this->BoundaryPointMap->push_back(vtkIntArray::New()); |
| 1551 |
//set it equal to prev timestep |
5436 |
vtkIntArray& bpMap = *this->BoundaryPointMap->back(); |
| 1552 |
//if no prev set to "constant" dir |
5437 |
vtkFloatArray *boundaryPointArray = vtkFloatArray::New(); |
| 1553 |
if(!polyMeshFound) |
5438 |
boundaryPointArray->SetNumberOfComponents(3); |
|
|
5439 |
int oldPointJ = -1; |
| 5440 |
for(int j = 0; j < nBoundaryPoints; j++) |
| 1554 |
{ |
5441 |
{ |
| 1555 |
if(i != 0) |
5442 |
const int pointJ = boundaryPointList->GetValue(j); |
| 1556 |
{ |
5443 |
if(pointJ != oldPointJ) |
| 1557 |
//set points/faces location to previous timesteps value |
|
|
| 1558 |
this->PolyMeshPointsDir->value[i] = this->PolyMeshPointsDir->value[i-1]; |
| 1559 |
this->PolyMeshFacesDir->value[i] = this->PolyMeshFacesDir->value[i-1]; |
| 1560 |
} |
| 1561 |
else |
| 1562 |
{ |
5444 |
{ |
| 1563 |
//set points/faces to constant |
5445 |
oldPointJ = pointJ; |
| 1564 |
this->PolyMeshPointsDir->value[i] = vtkstd::string("constant"); |
5446 |
boundaryPointArray->InsertNextTuple(pointArray->GetPointer(3 * pointJ)); |
| 1565 |
this->PolyMeshFacesDir->value[i] = vtkstd::string("constant"); |
5447 |
bpMap.InsertNextValue(pointJ); |
| 1566 |
} |
5448 |
} |
| 1567 |
} |
5449 |
} |
| 1568 |
directory->Delete(); |
5450 |
boundaryPointArray->Squeeze(); |
| 1569 |
} |
5451 |
bpMap.Squeeze(); |
|
|
5452 |
boundaryPointList->Delete(); |
| 5453 |
vtkPoints *boundaryPoints = vtkPoints::New(); |
| 5454 |
boundaryPoints->SetData(boundaryPointArray); |
| 5455 |
boundaryPointArray->Delete(); |
| 1570 |
|
5456 |
|
| 1571 |
vtkDebugMacro(<<"Points/faces list created"); |
5457 |
// set points for boundary |
| 1572 |
return; |
5458 |
bm.SetPoints(boundaryPoints); |
| 1573 |
} |
5459 |
boundaryPoints->Delete(); |
| 1574 |
|
5460 |
|
| 1575 |
// **************************************************************************** |
5461 |
// set the name of boundary |
| 1576 |
// Method: vtkOpenFOAMReader::GetDataType |
5462 |
this->SetDataObjectName(&bm, boundaryDict[boundaryI].boundaryName.c_str()); |
| 1577 |
// |
|
|
| 1578 |
// Purpose: |
| 1579 |
// determines whether a variable is a volume scalar, vector or neither |
| 1580 |
// for meta data |
| 1581 |
// |
| 1582 |
// **************************************************************************** |
| 1583 |
const char * vtkOpenFOAMReader::GetDataType(const char * pathIn, |
| 1584 |
const char * fileNameIn) |
| 1585 |
{ |
| 1586 |
vtkstd::string path(pathIn); |
| 1587 |
vtkstd::string fileName(fileNameIn); |
| 1588 |
vtkstd::string filePath = path+"/"+fileName; |
| 1589 |
vtkDebugMacro(<<"Get data type of: "<<filePath.c_str()); |
| 1590 |
stdString* tempStringStruct; |
| 1591 |
ifstream * input = new ifstream(filePath.c_str(), ios::in VTK_IOS_NOCREATE); |
| 1592 |
//make sure file exists |
| 1593 |
if(input->fail()) |
| 1594 |
{ |
| 1595 |
input->close(); |
| 1596 |
delete input; |
| 1597 |
return "Null"; |
| 1598 |
} |
| 1599 |
|
| 1600 |
vtkstd::string temp; |
| 1601 |
vtkstd::string foamClass; |
| 1602 |
vtksys_ios::stringstream tokenizer; |
| 1603 |
int opened; |
| 1604 |
|
5463 |
|
| 1605 |
//see if fileName is a file or directory |
5464 |
// insert faces to boundary mesh |
| 1606 |
vtkDirectory * directory = vtkDirectory::New(); |
5465 |
this->InsertFacesToGrid(&bm, facesPoints, startFace, endFace, &bpMap, |
| 1607 |
opened = directory->Open(filePath.c_str()); |
5466 |
facePointsVtkId, NULL, true); |
| 1608 |
directory->Delete(); |
5467 |
bpMap.ClearLookup(); |
| 1609 |
if(opened) |
|
|
| 1610 |
{ |
| 1611 |
input->close(); |
| 1612 |
delete input; |
| 1613 |
return "Directory"; |
| 1614 |
} |
5468 |
} |
| 1615 |
|
5469 |
|
| 1616 |
//find class entry |
5470 |
nBoundaryPointsList->Delete(); |
| 1617 |
tempStringStruct = this->GetLine(input); |
5471 |
facePointsVtkId->Delete(); |
| 1618 |
temp = tempStringStruct->value; |
|
|
| 1619 |
delete tempStringStruct; |
| 1620 |
while(temp.find("class") == vtkstd::string::npos && !input->eof()) |
| 1621 |
{ |
| 1622 |
tempStringStruct = this->GetLine(input); |
| 1623 |
temp = tempStringStruct->value; |
| 1624 |
delete tempStringStruct; |
| 1625 |
} |
| 1626 |
|
5472 |
|
| 1627 |
//return type |
5473 |
if(this->CreateCellToPoint) |
| 1628 |
if(!input->eof()) |
|
|
| 1629 |
{ |
5474 |
{ |
| 1630 |
temp.erase(temp.begin()+temp.find(";")); |
5475 |
this->AllBoundariesPointMap = vtkIntArray::New(); |
| 1631 |
//PARSE OUT CLASS TYPE |
5476 |
vtkIntArray &abpMap = *this->AllBoundariesPointMap; |
| 1632 |
tokenizer << temp; |
5477 |
abpMap.SetNumberOfValues(nAllBoundaryPoints); |
| 1633 |
//while(tokenizer >> foamClass); |
5478 |
|
| 1634 |
while(!tokenizer.eof()) |
5479 |
// create lists of internal points and AllBoundaries points |
| 1635 |
{ |
5480 |
int nInternalPoints = 0; |
| 1636 |
tokenizer >> foamClass; |
5481 |
for(int pointI = 0, allBoundaryPointI = 0; pointI < this->NumPoints; |
| 1637 |
} |
5482 |
pointI++) |
| 1638 |
//return scalar, vector, or invalid |
|
|
| 1639 |
if(foamClass =="volScalarField") |
| 1640 |
{ |
5483 |
{ |
| 1641 |
input->close(); |
5484 |
const int globalPointId = this->InternalPoints->GetValue(pointI); |
| 1642 |
delete input; |
5485 |
if(globalPointId == -1) |
| 1643 |
return "Scalar"; |
5486 |
{ |
|
|
5487 |
this->InternalPoints->SetValue(nInternalPoints, pointI); |
| 5488 |
nInternalPoints++; |
| 5489 |
} |
| 5490 |
else |
| 5491 |
{ |
| 5492 |
abpMap.SetValue(allBoundaryPointI, pointI); |
| 5493 |
allBoundaryPointI++; |
| 5494 |
} |
| 1644 |
} |
5495 |
} |
| 1645 |
else if (foamClass =="volVectorField") |
5496 |
// shrink to the number of internal points |
|
|
5497 |
if(nInternalPoints > 0) |
| 1646 |
{ |
5498 |
{ |
| 1647 |
input->close(); |
5499 |
this->InternalPoints->Resize(nInternalPoints); |
| 1648 |
delete input; |
|
|
| 1649 |
return "Vector"; |
| 1650 |
} |
5500 |
} |
| 1651 |
else |
5501 |
else |
| 1652 |
{ |
5502 |
{ |
| 1653 |
input->close(); |
5503 |
this->InternalPoints->Delete(); |
| 1654 |
delete input; |
5504 |
this->InternalPoints = NULL; |
| 1655 |
return "Invalid"; |
|
|
| 1656 |
} |
5505 |
} |
|
|
5506 |
|
| 5507 |
// set dummy vtkPoints to tell the grid the number of points |
| 5508 |
// (otherwise GetPointCells will crash) |
| 5509 |
vtkPoints *allBoundaryPoints = vtkPoints::New(); |
| 5510 |
allBoundaryPoints->SetNumberOfPoints(abpMap.GetNumberOfTuples()); |
| 5511 |
this->AllBoundaries->SetPoints(allBoundaryPoints); |
| 5512 |
allBoundaryPoints->Delete(); |
| 1657 |
} |
5513 |
} |
| 1658 |
|
5514 |
|
| 1659 |
//if the file format is wrong return invalid |
5515 |
vtkDebugMacro(<<"Boundary mesh created"); |
| 1660 |
else |
5516 |
return boundaryMesh; |
|
|
5517 |
} |
| 5518 |
|
| 5519 |
//----------------------------------------------------------------------------- |
| 5520 |
// truncate face owner to have only boundary face info |
| 5521 |
void vtkOpenFOAMReader::TruncateFaceOwner() |
| 5522 |
{ |
| 5523 |
const int boundaryStartFace = this->BoundaryDict->operator[](0).startFace; |
| 5524 |
// all the boundary faces |
| 5525 |
const int nBoundaryFaces |
| 5526 |
= this->FaceOwner->GetNumberOfTuples() - boundaryStartFace; |
| 5527 |
memmove(this->FaceOwner->GetPointer(0), |
| 5528 |
this->FaceOwner->GetPointer(boundaryStartFace), |
| 5529 |
sizeof(int) * nBoundaryFaces); |
| 5530 |
this->FaceOwner->Resize(nBoundaryFaces); |
| 5531 |
} |
| 5532 |
|
| 5533 |
//----------------------------------------------------------------------------- |
| 5534 |
// move polyhedral cell centroids |
| 5535 |
vtkPoints * vtkOpenFOAMReader::MoveInternalMesh( |
| 5536 |
vtkUnstructuredGrid *internalMesh, vtkFloatArray *pointArray) |
| 5537 |
{ |
| 5538 |
if(this->DecomposePolyhedra) |
| 1661 |
{ |
5539 |
{ |
| 1662 |
input->close(); |
5540 |
const int nAdditionalCells = this->AdditionalCellPoints->size(); |
| 1663 |
delete input; |
5541 |
pointArray->Resize(this->NumPoints + nAdditionalCells); |
| 1664 |
return "invalid"; |
5542 |
for(int i = 0; i < nAdditionalCells; i++) |
| 1665 |
} |
5543 |
{ |
|
|
5544 |
vtkIntArray *polyCellPoints = this->AdditionalCellPoints->operator[](i); |
| 5545 |
float centroid[3]; |
| 5546 |
centroid[0] = centroid[1] = centroid[2] = 0.0F; |
| 5547 |
const int nCellPoints = polyCellPoints->GetDataSize(); |
| 5548 |
for(int j = 0; j < nCellPoints; j++) |
| 5549 |
{ |
| 5550 |
float *pointK = pointArray->GetPointer(3 * polyCellPoints->GetValue(j)); |
| 5551 |
centroid[0] += pointK[0]; |
| 5552 |
centroid[1] += pointK[1]; |
| 5553 |
centroid[2] += pointK[2]; |
| 5554 |
} |
| 5555 |
float weight |
| 5556 |
= (nCellPoints ? 1.0F / static_cast<float>(nCellPoints) : 0.0F); |
| 5557 |
centroid[0] *= weight; |
| 5558 |
centroid[1] *= weight; |
| 5559 |
centroid[2] *= weight; |
| 5560 |
pointArray->InsertTuple(this->NumPoints + i, centroid); |
| 5561 |
} |
| 5562 |
} |
| 5563 |
// instantiate the points class |
| 5564 |
vtkPoints* points = vtkPoints::New(); |
| 5565 |
points->SetData(pointArray); |
| 5566 |
internalMesh->SetPoints(points); |
| 5567 |
return points; |
| 1666 |
} |
5568 |
} |
| 1667 |
|
5569 |
|
| 1668 |
// **************************************************************************** |
5570 |
//----------------------------------------------------------------------------- |
| 1669 |
// Method: vtkOpenFOAMReader::GetInternalVariableAtTimestep |
5571 |
// move boundary points |
| 1670 |
// |
5572 |
void vtkOpenFOAMReader::MoveBoundaryMesh(unstructuredGridVector *boundaryMesh, |
| 1671 |
// Purpose: |
5573 |
vtkFloatArray *pointArray) |
| 1672 |
// returns the values for a request variable for the internal mesh |
|
|
| 1673 |
// |
| 1674 |
// **************************************************************************** |
| 1675 |
vtkDoubleArray * vtkOpenFOAMReader::GetInternalVariableAtTimestep |
| 1676 |
(const char * varNameIn, int timeState) |
| 1677 |
{ |
5574 |
{ |
| 1678 |
vtkstd::string varName(varNameIn); |
5575 |
const vtkFoamBoundaryDict& bDict = *this->BoundaryDict; |
| 1679 |
vtksys_ios::stringstream varPath; |
|
|
| 1680 |
varPath << this->PathPrefix->value << this->Steps[timeState] << "/" << varName; |
| 1681 |
vtkDebugMacro(<<"Get internal variable: "<<varPath.str().c_str()); |
| 1682 |
vtkDoubleArray *data = vtkDoubleArray::New(); |
| 1683 |
|
5576 |
|
| 1684 |
vtkstd::string temp; |
5577 |
for(size_t boundaryI = 0, activeBoundaryI = 0; |
| 1685 |
stdString* tempStringStruct; |
5578 |
boundaryI < bDict.size(); boundaryI++) |
| 1686 |
bool binaryWriteFormat; |
|
|
| 1687 |
ifstream * input = new ifstream(varPath.str().c_str(), ios::in VTK_IOS_NOCREATE); |
| 1688 |
//make sure file exists |
| 1689 |
if(input->fail()) |
| 1690 |
{ |
5579 |
{ |
| 1691 |
input->close(); |
5580 |
if(bDict[boundaryI].isActive) |
| 1692 |
delete input; |
5581 |
{ |
| 1693 |
return data; |
5582 |
vtkUnstructuredGrid& bm |
|
|
5583 |
= *boundaryMesh->operator[](activeBoundaryI); |
| 5584 |
vtkIntArray& bpMap = *this->BoundaryPointMap->operator[](activeBoundaryI); |
| 5585 |
const int nBoundaryPoints = bpMap.GetNumberOfTuples(); |
| 5586 |
vtkFloatArray *boundaryPointArray = vtkFloatArray::New(); |
| 5587 |
boundaryPointArray->SetNumberOfComponents(3); |
| 5588 |
boundaryPointArray->SetNumberOfTuples(nBoundaryPoints); |
| 5589 |
for(int pointI = 0; pointI < nBoundaryPoints; pointI++) |
| 5590 |
{ |
| 5591 |
boundaryPointArray->SetTuple(pointI, bpMap.GetValue(pointI), |
| 5592 |
pointArray); |
| 5593 |
} |
| 5594 |
vtkPoints *boundaryPoints = vtkPoints::New(); |
| 5595 |
boundaryPoints->SetData(boundaryPointArray); |
| 5596 |
boundaryPointArray->Delete(); |
| 5597 |
bm.SetPoints(boundaryPoints); |
| 5598 |
boundaryPoints->Delete(); |
| 5599 |
activeBoundaryI++; |
| 5600 |
} |
| 1694 |
} |
5601 |
} |
|
|
5602 |
} |
| 1695 |
|
5603 |
|
| 1696 |
//determine if file is binary or ascii |
5604 |
//----------------------------------------------------------------------------- |
| 1697 |
while(temp.find("format") == vtkstd::string::npos) |
5605 |
// as of now the function does not do interpolation, but do just averaging. |
|
|
5606 |
void vtkOpenFOAMReader:: InterpolateCellToPoint(vtkFloatArray *pData, |
| 5607 |
vtkFloatArray *iData, vtkUnstructuredGrid *mesh, vtkIntArray *pointList, |
| 5608 |
const int nPoints) |
| 5609 |
{ |
| 5610 |
if(nPoints == 0) |
| 1698 |
{ |
5611 |
{ |
| 1699 |
tempStringStruct = this->GetLine(input); |
5612 |
return; |
| 1700 |
temp = tempStringStruct->value; |
|
|
| 1701 |
delete tempStringStruct; |
| 1702 |
} |
5613 |
} |
| 1703 |
input->close(); |
|
|
| 1704 |
|
5614 |
|
| 1705 |
//reopen file in correct format |
5615 |
// a dummy call to let GetPointCells() build the cell links |
| 1706 |
if(temp.find("binary") != vtkstd::string::npos) |
5616 |
vtkIdList *pointCells = vtkIdList::New(); |
| 1707 |
{ |
5617 |
mesh->GetPointCells(0, pointCells); |
| 1708 |
#ifdef _WIN32 |
5618 |
pointCells->Delete(); |
| 1709 |
input->open(varPath.str().c_str(), ios::binary | ios::in VTK_IOS_NOCREATE); |
5619 |
|
| 1710 |
#else |
5620 |
vtkCellLinks *cl = mesh->GetCellLinks(); |
| 1711 |
input->open(varPath.str().c_str(), ios::in VTK_IOS_NOCREATE); |
5621 |
const int nComponents = iData->GetNumberOfComponents(); |
| 1712 |
#endif |
5622 |
|
| 1713 |
binaryWriteFormat = true; |
5623 |
if(nComponents == 1) |
|
|
5624 |
{ |
| 5625 |
// a special case with the innermost componentI loop unrolled |
| 5626 |
float *tuples = iData->GetPointer(0); |
| 5627 |
for(int pointI = 0; pointI < nPoints; pointI++) |
| 5628 |
{ |
| 5629 |
const int pI = (pointList ? pointList->GetValue(pointI) : pointI); |
| 5630 |
const vtkCellLinks::Link &l = cl->GetLink(pI); |
| 5631 |
const int nCells = static_cast<int>(l.ncells); |
| 5632 |
const vtkIdType *cells = l.cells; |
| 5633 |
// use double intermediate variables for precision |
| 5634 |
double interpolatedValue = 0.0; |
| 5635 |
for(int cellI = 0; cellI < nCells; cellI++) |
| 5636 |
{ |
| 5637 |
interpolatedValue += tuples[cells[cellI]]; |
| 5638 |
} |
| 5639 |
interpolatedValue |
| 5640 |
= (nCells ? interpolatedValue / static_cast<double>(nCells) : 0.0); |
| 5641 |
pData->SetValue(pI, interpolatedValue); |
| 5642 |
} |
| 5643 |
} |
| 5644 |
else if(nComponents == 3) |
| 5645 |
{ |
| 5646 |
// a special case with the innermost componentI loop unrolled |
| 5647 |
float *pDataPtr = pData->GetPointer(0); |
| 5648 |
for(int pointI = 0; pointI < nPoints; pointI++) |
| 5649 |
{ |
| 5650 |
const int pI = (pointList ? pointList->GetValue(pointI) : pointI); |
| 5651 |
const vtkCellLinks::Link &l = cl->GetLink(pI); |
| 5652 |
const int nCells = static_cast<int>(l.ncells); |
| 5653 |
const vtkIdType *cells = l.cells; |
| 5654 |
// use double intermediate variables for precision |
| 5655 |
const double weight = (nCells ? 1.0 / static_cast<double>(nCells) : 0.0); |
| 5656 |
double summedValue0 = 0.0, summedValue1 = 0.0, summedValue2 = 0.0; |
| 5657 |
|
| 5658 |
// hand unrolling |
| 5659 |
for(int cellI = 0; cellI < nCells; cellI++) |
| 5660 |
{ |
| 5661 |
const float *tuple = iData->GetPointer(3 * cells[cellI]); |
| 5662 |
summedValue0 += tuple[0]; |
| 5663 |
summedValue1 += tuple[1]; |
| 5664 |
summedValue2 += tuple[2]; |
| 5665 |
} |
| 5666 |
|
| 5667 |
float *interpolatedValue = &pDataPtr[3 * pI]; |
| 5668 |
interpolatedValue[0] = weight * summedValue0; |
| 5669 |
interpolatedValue[1] = weight * summedValue1; |
| 5670 |
interpolatedValue[2] = weight * summedValue2; |
| 5671 |
} |
| 1714 |
} |
5672 |
} |
| 1715 |
else |
5673 |
else |
| 1716 |
{ |
5674 |
{ |
| 1717 |
input->open(varPath.str().c_str(),ios::in); |
5675 |
float *pDataPtr = pData->GetPointer(0); |
| 1718 |
binaryWriteFormat = false; |
5676 |
for(int pointI = 0; pointI < nPoints; pointI++) |
|
|
5677 |
{ |
| 5678 |
const int pI = (pointList ? pointList->GetValue(pointI) : pointI); |
| 5679 |
const vtkCellLinks::Link &l = cl->GetLink(pI); |
| 5680 |
const int nCells = static_cast<int>(l.ncells); |
| 5681 |
const vtkIdType *cells = l.cells; |
| 5682 |
// use double intermediate variables for precision |
| 5683 |
const double weight = (nCells ? 1.0 / static_cast<double>(nCells) : 0.0); |
| 5684 |
float *interpolatedValue = &pDataPtr[nComponents * pI]; |
| 5685 |
// a bit strange loop order but this works fastest |
| 5686 |
for(int componentI = 0; componentI < nComponents; componentI++) |
| 5687 |
{ |
| 5688 |
const float *tuple = iData->GetPointer(componentI); |
| 5689 |
double summedValue = 0.0; |
| 5690 |
for(int cellI = 0; cellI < nCells; cellI++) |
| 5691 |
{ |
| 5692 |
summedValue += tuple[nComponents * cells[cellI]]; |
| 5693 |
} |
| 5694 |
interpolatedValue[componentI] = weight * summedValue; |
| 5695 |
} |
| 5696 |
} |
| 1719 |
} |
5697 |
} |
|
|
5698 |
} |
| 1720 |
|
5699 |
|
| 1721 |
vtkstd::string foamClass; |
5700 |
//----------------------------------------------------------------------------- |
| 1722 |
vtksys_ios::stringstream tokenizer; |
5701 |
bool vtkOpenFOAMReader::ReadFieldFile(vtkFoamIOobject *ioPtr, |
| 1723 |
double value; |
5702 |
vtkFoamDict *dictPtr, const char *varNameIn, int timeState, |
| 1724 |
|
5703 |
vtkDataArraySelection *selection) |
| 1725 |
//find class |
5704 |
{ |
| 1726 |
tempStringStruct = this->GetLine(input); |
5705 |
vtkStdString varPath = *this->PathPrefix |
| 1727 |
temp = tempStringStruct->value; |
5706 |
+ this->TimeNames->GetValue(timeState) + "/" + vtkStdString(varNameIn); |
| 1728 |
delete tempStringStruct; |
5707 |
vtkDebugMacro(<<"Get variable: "<<varPath.c_str()); |
| 1729 |
|
5708 |
|
| 1730 |
while(temp.find("class") == vtkstd::string::npos) |
5709 |
// open the file |
|
|
5710 |
vtkFoamIOobject &io = *ioPtr; |
| 5711 |
if(!io.open(varPath)) |
| 1731 |
{ |
5712 |
{ |
| 1732 |
tempStringStruct = this->GetLine(input); |
5713 |
vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": " |
| 1733 |
temp = tempStringStruct->value; |
5714 |
<< io.error().c_str()); |
| 1734 |
delete tempStringStruct; |
5715 |
return false; |
| 1735 |
} |
5716 |
} |
| 1736 |
temp.erase(temp.begin()+temp.find(";")); |
5717 |
|
| 1737 |
tokenizer << temp; |
5718 |
// if the variable is disabled on selection panel then skip it |
| 1738 |
//while(tokenizer >> foamClass); |
5719 |
if(selection->ArrayExists(io.objectName().c_str()) |
| 1739 |
while(!tokenizer.eof()) |
5720 |
&& !selection->ArrayIsEnabled(io.objectName().c_str())) |
| 1740 |
{ |
5721 |
{ |
| 1741 |
tokenizer >> foamClass; |
5722 |
return false; |
| 1742 |
} |
5723 |
} |
| 1743 |
temp=""; |
5724 |
|
| 1744 |
//create scalar arrays |
5725 |
// read the field file into dictionary |
| 1745 |
if(foamClass =="volScalarField") |
5726 |
vtkFoamDict &dict = *dictPtr; |
|
|
5727 |
if(!dict.read(io)) |
| 1746 |
{ |
5728 |
{ |
| 1747 |
while(temp.find("internalField") == vtkstd::string::npos) |
5729 |
vtkErrorMacro(<<"Error reading line " << io.lineNumber() |
| 1748 |
{ |
5730 |
<< " of " << io.fileName().c_str() << ": " << io.error().c_str()); |
| 1749 |
tempStringStruct = this->GetLine(input); |
5731 |
return false; |
| 1750 |
temp = tempStringStruct->value; |
5732 |
} |
| 1751 |
delete tempStringStruct; |
|
|
| 1752 |
} |
| 1753 |
//nonuniform |
| 1754 |
if(!(temp.find("nonuniform") == vtkstd::string::npos)) |
| 1755 |
{ |
| 1756 |
//create an array |
| 1757 |
tempStringStruct = this->GetLine(input); |
| 1758 |
temp = tempStringStruct->value; |
| 1759 |
delete tempStringStruct; |
| 1760 |
|
5733 |
|
| 1761 |
int scalarCount; |
5734 |
if(dict.type() != vtkFoamToken::DICTIONARY) |
| 1762 |
tokenizer.clear(); |
5735 |
{ |
| 1763 |
tokenizer << temp; |
5736 |
vtkErrorMacro(<<"File " << io.fileName().c_str() |
| 1764 |
tokenizer >> scalarCount; |
5737 |
<< "is not valid as a field file"); |
| 1765 |
data->SetNumberOfValues(NumCells); |
5738 |
return false; |
|
|
5739 |
} |
| 5740 |
return true; |
| 5741 |
} |
| 1766 |
|
5742 |
|
| 1767 |
//binary data |
5743 |
//----------------------------------------------------------------------------- |
| 1768 |
if(binaryWriteFormat) |
5744 |
vtkFloatArray *vtkOpenFOAMReader::FillField(vtkFoamEntry *entryPtr, |
|
|
5745 |
int nElements, vtkFoamIOobject *ioPtr, const vtkStdString *fieldType) |
| 5746 |
{ |
| 5747 |
vtkFloatArray *data; |
| 5748 |
vtkFoamEntry &entry = *entryPtr; |
| 5749 |
const vtkStdString &className = ioPtr->className(); |
| 5750 |
|
| 5751 |
// "uniformValue" keyword is for uniformFixedValue B.C. |
| 5752 |
if(entry.firstValue().isUniform() || entry.keyword() == "uniformValue") |
| 5753 |
{ |
| 5754 |
if(entry.firstValue().type() == vtkFoamToken::SCALAR |
| 5755 |
|| entry.firstValue().type() == vtkFoamToken::LABEL) |
| 5756 |
{ |
| 5757 |
const float num = entry.toFloat(); |
| 5758 |
data = vtkFloatArray::New(); |
| 5759 |
data->SetNumberOfValues(nElements); |
| 5760 |
for(int i = 0; i < nElements; i++) |
| 1769 |
{ |
5761 |
{ |
| 1770 |
//add values to array |
5762 |
data->SetValue(i, num); |
| 1771 |
input->get(); //parenthesis |
5763 |
} |
| 1772 |
for(int i = 0; i < scalarCount; i++) |
5764 |
} |
|
|
5765 |
else |
| 5766 |
{ |
| 5767 |
float tupleBuffer[9], *tuple; |
| 5768 |
int nComponents; |
| 5769 |
// have to determine the type of vector |
| 5770 |
if(entry.firstValue().type() == vtkFoamToken::LABELLIST) |
| 5771 |
{ |
| 5772 |
vtkIntArray &ll = entry.labelList(); |
| 5773 |
nComponents = ll.GetNumberOfTuples(); |
| 5774 |
for(int componentI = 0; componentI < nComponents; componentI++) |
| 1773 |
{ |
5775 |
{ |
| 1774 |
input->read((char *) &value, sizeof(double)); |
5776 |
tupleBuffer[componentI] = static_cast<float>(ll.GetValue(componentI)); |
| 1775 |
data->SetValue(i, value); |
|
|
| 1776 |
} |
5777 |
} |
|
|
5778 |
tuple = tupleBuffer; |
| 5779 |
} |
| 5780 |
else if(entry.firstValue().type() == vtkFoamToken::SCALARLIST) |
| 5781 |
{ |
| 5782 |
vtkFloatArray& sl = entry.scalarList(); |
| 5783 |
nComponents = sl.GetSize(); |
| 5784 |
tuple = sl.GetPointer(0); |
| 1777 |
} |
5785 |
} |
| 1778 |
|
|
|
| 1779 |
//ascii data |
| 1780 |
else |
5786 |
else |
| 1781 |
{ |
5787 |
{ |
| 1782 |
//add values to array |
5788 |
vtkErrorMacro(<<"Wrong list type for uniform field"); |
| 1783 |
tempStringStruct = this->GetLine(input); |
5789 |
return NULL; |
| 1784 |
temp = tempStringStruct->value; |
5790 |
} |
| 1785 |
delete tempStringStruct; //discard ( |
|
|
| 1786 |
|
5791 |
|
| 1787 |
for(int i = 0; i < scalarCount; i++) |
5792 |
if((*fieldType == "SphericalTensorField" && nComponents == 1) |
|
|
5793 |
|| (*fieldType == "VectorField" && nComponents == 3) |
| 5794 |
|| (*fieldType == "SymmTensorField" && nComponents == 6) |
| 5795 |
|| (*fieldType == "TensorField" && nComponents == 9)) |
| 5796 |
{ |
| 5797 |
data = vtkFloatArray::New(); |
| 5798 |
data->SetNumberOfComponents(nComponents); |
| 5799 |
data->SetNumberOfTuples(nElements); |
| 5800 |
#if PARAVIEW_VERSION_MAJOR >= 3 && PARAVIEW_VERSION_MINOR >= 3 |
| 5801 |
#if vtksys_DATE_STAMP_FULL >= 20080620 |
| 5802 |
// swap the components of symmTensor to match the component |
| 5803 |
// names in paraview |
| 5804 |
if(nComponents == 6) |
| 5805 |
{ |
| 5806 |
const float symxy = tuple[1], symxz = tuple[2], symyy = tuple[3]; |
| 5807 |
const float symyz = tuple[4], symzz = tuple[5]; |
| 5808 |
tuple[1] = symyy; |
| 5809 |
tuple[2] = symzz; |
| 5810 |
tuple[3] = symxy; |
| 5811 |
tuple[4] = symyz; |
| 5812 |
tuple[5] = symxz; |
| 5813 |
} |
| 5814 |
#endif |
| 5815 |
#endif |
| 5816 |
for(int i = 0; i < nElements; i++) |
| 1788 |
{ |
5817 |
{ |
| 1789 |
tempStringStruct = this->GetLine(input); |
5818 |
data->SetTuple(i, tuple); |
| 1790 |
temp = tempStringStruct->value; |
|
|
| 1791 |
delete tempStringStruct; |
| 1792 |
tokenizer.clear(); |
| 1793 |
tokenizer << temp; |
| 1794 |
tokenizer >> value; |
| 1795 |
data->SetValue(i, value); |
| 1796 |
} |
5819 |
} |
| 1797 |
} |
5820 |
} |
|
|
5821 |
else |
| 5822 |
{ |
| 5823 |
vtkErrorMacro(<< "Number of components and field class doesn't match " |
| 5824 |
<< "for " << ioPtr->objectName() << ". class = " << className |
| 5825 |
<< ", nComponents = " << nComponents); |
| 5826 |
return NULL; |
| 5827 |
} |
| 1798 |
} |
5828 |
} |
| 1799 |
|
5829 |
} |
| 1800 |
//uniform |
5830 |
else // nonuniform |
| 1801 |
else if(!(temp.find("uniform") == vtkstd::string::npos)) |
5831 |
{ |
|
|
5832 |
if((*fieldType == "ScalarField" |
| 5833 |
&& entry.firstValue().type() == vtkFoamToken::SCALARLIST) |
| 5834 |
|| ((*fieldType == "VectorField" || *fieldType == "SphericalTensorField" |
| 5835 |
|| *fieldType == "SymmTensorField" || *fieldType == "TensorField") |
| 5836 |
&& entry.firstValue().type() == vtkFoamToken::VECTORLIST)) |
| 5837 |
{ |
| 5838 |
const int nTuples = entry.scalarList().GetNumberOfTuples(); |
| 5839 |
if(nTuples != nElements) |
| 5840 |
{ |
| 5841 |
vtkErrorMacro(<<"Number of cells/points in mesh and field don't match: " |
| 5842 |
<< "mesh = " << nElements << ", field = " << nTuples); |
| 5843 |
return NULL; |
| 5844 |
} |
| 5845 |
data = static_cast<vtkFloatArray *>(entry.ptr()); |
| 5846 |
#if PARAVIEW_VERSION_MAJOR >= 3 && PARAVIEW_VERSION_MINOR >= 3 |
| 5847 |
#if vtksys_DATE_STAMP_FULL >= 20080620 |
| 5848 |
// swap the components of symmTensor to match the component |
| 5849 |
// names in paraview |
| 5850 |
const int nComponents = data->GetNumberOfComponents(); |
| 5851 |
if(nComponents == 6) |
| 5852 |
{ |
| 5853 |
for(int tupleI = 0; tupleI < nTuples; tupleI++) |
| 5854 |
{ |
| 5855 |
float *tuple = data->GetPointer(nComponents * tupleI); |
| 5856 |
const float symxy = tuple[1], symxz = tuple[2], symyy = tuple[3]; |
| 5857 |
const float symyz = tuple[4], symzz = tuple[5]; |
| 5858 |
tuple[1] = symyy; |
| 5859 |
tuple[2] = symzz; |
| 5860 |
tuple[3] = symxy; |
| 5861 |
tuple[4] = symyz; |
| 5862 |
tuple[5] = symxz; |
| 5863 |
} |
| 5864 |
} |
| 5865 |
#endif |
| 5866 |
#endif |
| 5867 |
} |
| 5868 |
else if(entry.firstValue().type() == vtkFoamToken::EMPTYLIST && |
| 5869 |
nElements <= 0) |
| 1802 |
{ |
5870 |
{ |
| 1803 |
//parse out the uniform value |
5871 |
data = vtkFloatArray::New(); |
| 1804 |
vtkstd::string token; |
5872 |
// set the number of components as appropriate if the list is empty |
| 1805 |
temp.erase(temp.begin()+temp.find(";")); |
5873 |
if(*fieldType == "ScalarField" || *fieldType == "SphericalTensorField") |
| 1806 |
tokenizer.clear(); |
|
|
| 1807 |
tokenizer << temp; |
| 1808 |
//while(tokenizer>>token); |
| 1809 |
while(!tokenizer.eof()) |
| 1810 |
{ |
5874 |
{ |
| 1811 |
tokenizer >> token; |
5875 |
data->SetNumberOfComponents(1); |
| 1812 |
} |
5876 |
} |
| 1813 |
tokenizer.clear(); |
5877 |
else if(*fieldType == "VectorField") |
| 1814 |
tokenizer << token; |
5878 |
{ |
| 1815 |
tokenizer >> value; |
5879 |
data->SetNumberOfComponents(3); |
| 1816 |
data->SetNumberOfValues(NumCells); |
5880 |
} |
| 1817 |
|
5881 |
else if(*fieldType == "SymmTensorField") |
| 1818 |
//create array of uniform values |
5882 |
{ |
| 1819 |
for(int i = 0; i < NumCells; i++) |
5883 |
data->SetNumberOfComponents(6); |
|
|
5884 |
} |
| 5885 |
else if(*fieldType == "TensorField") |
| 1820 |
{ |
5886 |
{ |
| 1821 |
data->SetValue(i, value); |
5887 |
data->SetNumberOfComponents(9); |
| 1822 |
} |
5888 |
} |
| 1823 |
} |
5889 |
} |
| 1824 |
|
|
|
| 1825 |
//no data |
| 1826 |
else |
5890 |
else |
| 1827 |
{ |
5891 |
{ |
| 1828 |
input->close(); |
5892 |
vtkErrorMacro(<< ioPtr->objectName().c_str() << " is not a valid " |
| 1829 |
delete input; |
5893 |
<< ioPtr->className().c_str()); |
| 1830 |
return data; |
5894 |
return NULL; |
| 1831 |
} |
5895 |
} |
| 1832 |
} |
5896 |
} |
|
|
5897 |
return data; |
| 5898 |
} |
| 1833 |
|
5899 |
|
| 1834 |
//create vector arrays |
5900 |
//----------------------------------------------------------------------------- |
| 1835 |
else if(foamClass == "volVectorField") |
5901 |
// convert OpenFOAM's dimension array representation to string |
|
|
5902 |
void vtkOpenFOAMReader::ConstructDimensions(vtkStdString *dimString, |
| 5903 |
vtkFoamDict *dictPtr) |
| 5904 |
{ |
| 5905 |
if(!AddDimensionsToArrayNames) |
| 1836 |
{ |
5906 |
{ |
| 1837 |
tempStringStruct = this->GetLine(input); |
5907 |
return; |
| 1838 |
temp = tempStringStruct->value; |
5908 |
} |
| 1839 |
delete tempStringStruct; |
5909 |
vtkFoamEntry &dimEntry = dictPtr->lookup("dimensions"); |
| 1840 |
while(temp.find("internalField") == vtkstd::string::npos) |
5910 |
if(dimEntry.found() |
| 1841 |
{ |
5911 |
&& dimEntry.firstValue().type() == vtkFoamToken::LABELLIST) |
| 1842 |
tempStringStruct = this->GetLine(input); |
5912 |
{ |
| 1843 |
temp = tempStringStruct->value; |
5913 |
vtkIntArray &dims = dimEntry.labelList(); |
| 1844 |
delete tempStringStruct; |
5914 |
if(dims.GetNumberOfTuples() == 7) |
| 1845 |
} |
|
|
| 1846 |
if(!(temp.find("nonuniform") == vtkstd::string::npos)) |
| 1847 |
{ |
5915 |
{ |
| 1848 |
//create an array |
5916 |
int dimSet[7]; |
| 1849 |
tempStringStruct = this->GetLine(input); |
5917 |
for(int dimI = 0; dimI < 7; dimI++) |
| 1850 |
temp = tempStringStruct->value; |
5918 |
{ |
| 1851 |
delete tempStringStruct; |
5919 |
dimSet[dimI] = dims.GetValue(dimI); |
| 1852 |
|
5920 |
} |
| 1853 |
int vectorCount; |
5921 |
static const char *units[7] = { "kg", "m", "s", "K", "mol", "A", "cd" }; |
| 1854 |
tokenizer.clear(); |
5922 |
vtksys_ios::ostringstream posDim, negDim; |
| 1855 |
tokenizer << temp; |
5923 |
int posSpc = 0, negSpc = 0; |
| 1856 |
tokenizer >> vectorCount; |
5924 |
if(dimSet[0] == 1 && dimSet[1] == -1 && dimSet[2] == -2) |
| 1857 |
data->SetNumberOfComponents(3); |
5925 |
{ |
| 1858 |
|
5926 |
posDim << "Pa"; |
| 1859 |
//binary data |
5927 |
dimSet[0] = dimSet[1] = dimSet[2] = 0; |
| 1860 |
if(binaryWriteFormat) |
5928 |
posSpc = 1; |
|
|
5929 |
} |
| 5930 |
for(int dimI = 0; dimI < 7; dimI++) |
| 5931 |
{ |
| 5932 |
const int dimDim = dimSet[dimI]; |
| 5933 |
if(dimDim > 0) |
| 5934 |
{ |
| 5935 |
if(posSpc) |
| 5936 |
{ |
| 5937 |
posDim << " "; |
| 5938 |
} |
| 5939 |
posDim << units[dimI]; |
| 5940 |
if(dimDim > 1) |
| 5941 |
{ |
| 5942 |
posDim << dimDim; |
| 5943 |
} |
| 5944 |
posSpc++; |
| 5945 |
} |
| 5946 |
else if(dimDim < 0) |
| 5947 |
{ |
| 5948 |
if(negSpc) |
| 5949 |
{ |
| 5950 |
negDim << " "; |
| 5951 |
} |
| 5952 |
negDim << units[dimI]; |
| 5953 |
if(dimDim < -1) |
| 5954 |
{ |
| 5955 |
negDim << -dimDim; |
| 5956 |
} |
| 5957 |
negSpc++; |
| 5958 |
} |
| 5959 |
} |
| 5960 |
*dimString += " [" + posDim.str(); |
| 5961 |
if(negSpc > 0) |
| 1861 |
{ |
5962 |
{ |
| 1862 |
//add values to the array |
5963 |
if(posSpc == 0) |
| 1863 |
input->get(); //parenthesis |
5964 |
{ |
| 1864 |
for(int i = 0; i < vectorCount; i++) |
5965 |
*dimString += "1"; |
|
|
5966 |
} |
| 5967 |
if(negSpc > 1) |
| 1865 |
{ |
5968 |
{ |
| 1866 |
input->read((char *) &value, sizeof(double)); |
5969 |
*dimString += "/(" + negDim.str() + ")"; |
| 1867 |
data->InsertComponent(i, 0, value); |
|
|
| 1868 |
input->read((char *) &value, sizeof(double)); |
| 1869 |
data->InsertComponent(i, 1, value); |
| 1870 |
input->read((char *) &value, sizeof(double)); |
| 1871 |
data->InsertComponent(i, 2, value); |
| 1872 |
} |
5970 |
} |
| 1873 |
} |
5971 |
else |
| 1874 |
|
|
|
| 1875 |
//ascii data |
| 1876 |
else |
| 1877 |
{ |
| 1878 |
//add values to the array |
| 1879 |
tempStringStruct = this->GetLine(input); |
| 1880 |
temp = tempStringStruct->value; |
| 1881 |
delete tempStringStruct; //discard ( |
| 1882 |
for(int i = 0; i < vectorCount; i++) |
| 1883 |
{ |
5972 |
{ |
| 1884 |
tempStringStruct = this->GetLine(input); |
5973 |
*dimString += "/" + negDim.str(); |
| 1885 |
temp = tempStringStruct->value; |
|
|
| 1886 |
delete tempStringStruct; |
| 1887 |
|
| 1888 |
//REMOVE BRACKETS |
| 1889 |
temp.erase(temp.begin()+temp.find("(")); |
| 1890 |
temp.erase(temp.begin()+temp.find(")")); |
| 1891 |
|
| 1892 |
//GRAB X,Y,&Z VALUES |
| 1893 |
tokenizer.clear(); |
| 1894 |
tokenizer << temp; |
| 1895 |
tokenizer >> value; |
| 1896 |
data->InsertComponent(i, 0, value); |
| 1897 |
tokenizer >> value; |
| 1898 |
data->InsertComponent(i, 1, value); |
| 1899 |
tokenizer >> value; |
| 1900 |
data->InsertComponent(i, 2, value); |
| 1901 |
} |
5974 |
} |
| 1902 |
} |
5975 |
} |
| 1903 |
} |
5976 |
else if(posSpc == 0) |
| 1904 |
else if(!(temp.find("uniform") == vtkstd::string::npos)) |
|
|
| 1905 |
{ |
| 1906 |
//create an array of uniform values |
| 1907 |
double value1, value2, value3; |
| 1908 |
|
| 1909 |
//parse out the uniform values |
| 1910 |
temp.erase(temp.begin(), temp.begin()+temp.find("(")+1); |
| 1911 |
temp.erase(temp.begin()+temp.find(")"), temp.end()); |
| 1912 |
tokenizer.clear(); |
| 1913 |
tokenizer << temp; |
| 1914 |
tokenizer >> value1; |
| 1915 |
tokenizer >> value2; |
| 1916 |
tokenizer >> value3; |
| 1917 |
data->SetNumberOfComponents(3); |
| 1918 |
for(int i = 0; i < NumCells; i++) |
| 1919 |
{ |
5977 |
{ |
| 1920 |
data->InsertComponent(i, 0, value1); |
5978 |
*dimString += "-"; |
| 1921 |
data->InsertComponent(i, 1, value2); |
|
|
| 1922 |
data->InsertComponent(i, 2, value3); |
| 1923 |
} |
5979 |
} |
| 1924 |
} |
5980 |
*dimString += "]"; |
| 1925 |
|
|
|
| 1926 |
//no data |
| 1927 |
else |
| 1928 |
{ |
| 1929 |
input->close(); |
| 1930 |
delete input; |
| 1931 |
return data; |
| 1932 |
} |
5981 |
} |
| 1933 |
} |
5982 |
} |
| 1934 |
input->close(); |
|
|
| 1935 |
delete input; |
| 1936 |
vtkDebugMacro(<<"Internal variable data read"); |
| 1937 |
return data; |
| 1938 |
} |
5983 |
} |
| 1939 |
|
5984 |
|
| 1940 |
// **************************************************************************** |
5985 |
//----------------------------------------------------------------------------- |
| 1941 |
// Method: vtkOpenFOAMReader::GetBoundaryVariableAtTimestep |
5986 |
void vtkOpenFOAMReader::GetVolFieldAtTimestep( |
| 1942 |
// |
5987 |
vtkUnstructuredGrid* internalMesh, unstructuredGridVector* boundaryMesh, |
| 1943 |
// Purpose: |
5988 |
vtkFoamBoundaryDict* boundaryDictPtr, const char* varNameIn, int timeState) |
| 1944 |
// returns the values for a request variable for a bondary region |
|
|
| 1945 |
// |
| 1946 |
// **************************************************************************** |
| 1947 |
vtkDoubleArray * vtkOpenFOAMReader::GetBoundaryVariableAtTimestep |
| 1948 |
(int boundaryIndex, const char * varNameIn, int timeState, |
| 1949 |
vtkUnstructuredGrid * internalMesh) |
| 1950 |
{ |
5989 |
{ |
| 1951 |
vtkstd::string varName(varNameIn); |
5990 |
vtkFoamIOobject io(*this->PathPrefix); |
| 1952 |
vtksys_ios::stringstream varPath; |
5991 |
vtkFoamDict dict; |
| 1953 |
varPath << this->PathPrefix->value << this->Steps[timeState] << "/" << varName; |
5992 |
if(!this->ReadFieldFile(&io, &dict, varNameIn, timeState, |
| 1954 |
vtkDebugMacro(<<"Get boundary variable: "<<varPath.str().c_str()); |
5993 |
this->CellDataArraySelection)) |
| 1955 |
vtkDoubleArray *data = vtkDoubleArray::New(); |
|
|
| 1956 |
|
| 1957 |
vtkstd::string temp; |
| 1958 |
stdString* tempStringStruct; |
| 1959 |
bool binaryWriteFormat; |
| 1960 |
ifstream * input = new ifstream(varPath.str().c_str(), ios::in VTK_IOS_NOCREATE); |
| 1961 |
//make sure file exists |
| 1962 |
if(input->fail()) |
| 1963 |
{ |
5994 |
{ |
| 1964 |
input->close(); |
5995 |
return; |
| 1965 |
delete input; |
|
|
| 1966 |
return data; |
| 1967 |
} |
5996 |
} |
| 1968 |
|
5997 |
|
| 1969 |
//determine if file is binary or ascii |
5998 |
if(io.className().substr(0, 3) != "vol") |
| 1970 |
while(temp.find("format") == vtkstd::string::npos) |
|
|
| 1971 |
{ |
5999 |
{ |
| 1972 |
tempStringStruct = this->GetLine(input); |
6000 |
vtkErrorMacro(<< io.objectName().c_str() << " is not a volField"); |
| 1973 |
temp = tempStringStruct->value; |
6001 |
return; |
| 1974 |
delete tempStringStruct; |
|
|
| 1975 |
} |
6002 |
} |
| 1976 |
input->close(); |
|
|
| 1977 |
|
6003 |
|
| 1978 |
//reopen file in correct format |
6004 |
vtkFoamEntry &iEntry = dict.lookup("internalField"); |
| 1979 |
if(temp.find("binary") != vtkstd::string::npos) |
6005 |
if(!iEntry.found()) |
| 1980 |
{ |
6006 |
{ |
| 1981 |
#ifdef _WIN32 |
6007 |
vtkErrorMacro(<<"internalField not found in " << io.fileName().c_str()); |
| 1982 |
input->open(varPath.str().c_str(), ios::binary | ios::in VTK_IOS_NOCREATE); |
6008 |
return; |
| 1983 |
#else |
|
|
| 1984 |
input->open(varPath.str().c_str(), ios::in VTK_IOS_NOCREATE); |
| 1985 |
#endif |
| 1986 |
binaryWriteFormat = true; |
| 1987 |
} |
6009 |
} |
| 1988 |
else |
6010 |
|
|
|
6011 |
if(iEntry.firstValue().type() == vtkFoamToken::EMPTYLIST) |
| 1989 |
{ |
6012 |
{ |
| 1990 |
input->open(varPath.str().c_str(),ios::in); |
6013 |
// if there's no cell there shouldn't be any boundary faces either |
| 1991 |
binaryWriteFormat = false; |
6014 |
if(this->NumCells > 0) |
|
|
6015 |
{ |
| 6016 |
vtkErrorMacro(<<"internalField of " << io.objectName().c_str() |
| 6017 |
<< " is empty"); |
| 6018 |
} |
| 6019 |
return; |
| 1992 |
} |
6020 |
} |
| 1993 |
|
6021 |
|
| 1994 |
vtkstd::string foamClass; |
6022 |
vtkStdString fieldType = io.className().substr(3, vtkStdString::npos); |
| 1995 |
vtksys_ios::stringstream tokenizer; |
6023 |
vtkFloatArray *iData = this->FillField(&iEntry, this->NumCells, &io, |
| 1996 |
double value; |
6024 |
&fieldType); |
| 1997 |
|
6025 |
if(iData == NULL) |
| 1998 |
//find class |
|
|
| 1999 |
tempStringStruct = this->GetLine(input); |
| 2000 |
temp = tempStringStruct->value; |
| 2001 |
delete tempStringStruct; |
| 2002 |
while(temp.find("class") == vtkstd::string::npos) |
| 2003 |
{ |
6026 |
{ |
| 2004 |
tempStringStruct = this->GetLine(input); |
6027 |
return; |
| 2005 |
temp = tempStringStruct->value; |
|
|
| 2006 |
delete tempStringStruct; |
| 2007 |
} |
6028 |
} |
| 2008 |
temp.erase(temp.begin()+temp.find(";")); |
6029 |
|
| 2009 |
tokenizer << temp; |
6030 |
vtkStdString dimString; |
| 2010 |
//while(tokenizer >> foamClass); |
6031 |
this->ConstructDimensions(&dimString, &dict); |
| 2011 |
while(!tokenizer.eof()) |
6032 |
|
|
|
6033 |
vtkFloatArray *acData = NULL, *ctpData = NULL; |
| 6034 |
|
| 6035 |
if(this->CreateCellToPoint) |
| 2012 |
{ |
6036 |
{ |
| 2013 |
tokenizer >> foamClass; |
6037 |
acData = vtkFloatArray::New(); |
|
|
6038 |
acData->SetNumberOfComponents(iData->GetNumberOfComponents()); |
| 6039 |
acData->SetNumberOfTuples(this->FaceOwner->GetNumberOfTuples()); |
| 2014 |
} |
6040 |
} |
| 2015 |
temp=""; |
|
|
| 2016 |
//create scalar arrays |
| 2017 |
if(foamClass =="volScalarField") |
| 2018 |
{ |
| 2019 |
//find desired mesh |
| 2020 |
while(temp.find(this->BoundaryNames->value[boundaryIndex]) == |
| 2021 |
vtkstd::string::npos && !input->eof()) |
| 2022 |
{ |
| 2023 |
tempStringStruct = this->GetLine(input); |
| 2024 |
temp = tempStringStruct->value; |
| 2025 |
delete tempStringStruct; |
| 2026 |
} |
| 2027 |
if(input->eof()) |
| 2028 |
{ |
| 2029 |
input->close(); |
| 2030 |
delete input; |
| 2031 |
return data; |
| 2032 |
} |
| 2033 |
//find value entry |
| 2034 |
while(temp.find("}") == vtkstd::string::npos && |
| 2035 |
temp.find("value ") == vtkstd::string::npos) |
| 2036 |
{ |
| 2037 |
tempStringStruct = this->GetLine(input); |
| 2038 |
temp = tempStringStruct->value; |
| 2039 |
delete tempStringStruct; //find value |
| 2040 |
} |
| 2041 |
|
6041 |
|
| 2042 |
//nonuniform |
6042 |
if(iData->GetSize() > 0) |
| 2043 |
if(!(temp.find("nonuniform") == vtkstd::string::npos)) |
6043 |
{ |
|
|
6044 |
// Add field only if internal Mesh exists (skip if not selected). |
| 6045 |
// Note we still need to read internalField even if internal mesh is |
| 6046 |
// not selected, since boundaries without value entries may refer to |
| 6047 |
// the internalField. |
| 6048 |
if(internalMesh != NULL) |
| 2044 |
{ |
6049 |
{ |
| 2045 |
|
6050 |
int nAdditionalCells = 0; |
| 2046 |
//binary data |
6051 |
if(this->DecomposePolyhedra) |
| 2047 |
if(binaryWriteFormat) |
|
|
| 2048 |
{ |
6052 |
{ |
| 2049 |
//create an array |
6053 |
// add values for decomposed cells |
| 2050 |
tempStringStruct = this->GetLine(input); |
6054 |
nAdditionalCells = this->AdditionalCellIds->GetNumberOfTuples(); |
| 2051 |
temp = tempStringStruct->value; |
6055 |
iData->Resize(this->NumCells + nAdditionalCells); |
| 2052 |
delete tempStringStruct; |
6056 |
for(int i = 0; i < nAdditionalCells; i++) |
| 2053 |
|
|
|
| 2054 |
int scalarCount; |
| 2055 |
tokenizer.clear(); |
| 2056 |
tokenizer << temp; |
| 2057 |
tokenizer >> scalarCount; |
| 2058 |
data->SetNumberOfValues(scalarCount); |
| 2059 |
|
| 2060 |
//assign values to the array |
| 2061 |
input->get(); //parenthesis |
| 2062 |
for(int i = 0; i < scalarCount; i++) |
| 2063 |
{ |
6057 |
{ |
| 2064 |
input->read((char *) &value, sizeof(double)); |
6058 |
iData->InsertTuple(this->NumCells + i, |
| 2065 |
data->SetValue(i, value); |
6059 |
static_cast<vtkIdType>(this->AdditionalCellIds->GetValue(i)), iData); |
| 2066 |
} |
6060 |
} |
| 2067 |
} |
6061 |
} |
| 2068 |
|
6062 |
|
| 2069 |
//ascii data |
6063 |
// set data to internal mesh |
| 2070 |
else |
6064 |
this->AddArrayToFieldData(internalMesh->GetCellData(), iData, |
|
|
6065 |
io.objectName() + dimString); |
| 6066 |
|
| 6067 |
if(this->CreateCellToPoint) |
| 2071 |
{ |
6068 |
{ |
| 2072 |
temp.erase(temp.begin(), temp.begin()+temp.find(">")+1); |
6069 |
// Create cell-to-point interpolated data |
| 2073 |
//ascii data with 10 or less values are on the same line |
6070 |
ctpData = vtkFloatArray::New(); |
| 2074 |
//>10 |
6071 |
ctpData->SetNumberOfComponents(iData->GetNumberOfComponents()); |
| 2075 |
if(temp == vtkstd::string(" ")) |
6072 |
ctpData->SetNumberOfTuples( |
|
|
6073 |
internalMesh->GetPoints()->GetNumberOfPoints()); |
| 6074 |
if(this->InternalPoints != NULL) |
| 2076 |
{ |
6075 |
{ |
| 2077 |
//create an array of data |
6076 |
this->InterpolateCellToPoint(ctpData, iData, internalMesh, |
| 2078 |
tempStringStruct = this->GetLine(input); |
6077 |
this->InternalPoints, this->InternalPoints->GetNumberOfTuples()); |
| 2079 |
temp = tempStringStruct->value; |
|
|
| 2080 |
delete tempStringStruct; |
| 2081 |
|
| 2082 |
int scalarCount; |
| 2083 |
tokenizer.clear(); |
| 2084 |
tokenizer << temp; |
| 2085 |
tokenizer >> scalarCount; |
| 2086 |
data->SetNumberOfValues(scalarCount); |
| 2087 |
tempStringStruct = this->GetLine(input); |
| 2088 |
temp = tempStringStruct->value; |
| 2089 |
delete tempStringStruct; //discard ( |
| 2090 |
|
| 2091 |
for(int i = 0; i < scalarCount; i++) |
| 2092 |
{ |
| 2093 |
tempStringStruct = this->GetLine(input); |
| 2094 |
temp = tempStringStruct->value; |
| 2095 |
delete tempStringStruct; |
| 2096 |
|
| 2097 |
tokenizer.clear(); |
| 2098 |
tokenizer << temp; |
| 2099 |
tokenizer >> value; |
| 2100 |
data->SetValue(i, value); |
| 2101 |
} |
| 2102 |
} |
6078 |
} |
| 2103 |
//=<10 |
|
|
| 2104 |
else |
| 2105 |
{ |
| 2106 |
//create an array with data |
| 2107 |
int scalarCount; |
| 2108 |
tokenizer.clear(); |
| 2109 |
tokenizer << temp; |
| 2110 |
tokenizer >> scalarCount; |
| 2111 |
data->SetNumberOfValues(scalarCount); |
| 2112 |
temp.erase(temp.begin(), temp.begin()+temp.find("(")+1); |
| 2113 |
temp.erase(temp.begin()+temp.find(")"), temp.end()); |
| 2114 |
|
6079 |
|
| 2115 |
tokenizer.clear(); |
6080 |
if(this->DecomposePolyhedra) |
| 2116 |
tokenizer << temp; |
6081 |
{ |
| 2117 |
for(int i = 0; i < scalarCount; i++) |
6082 |
// assign cell values to additional points |
|
|
6083 |
for(int cellI = 0, oldCellId = -1, pointI = this->NumPoints; |
| 6084 |
cellI < nAdditionalCells; cellI++) |
| 2118 |
{ |
6085 |
{ |
| 2119 |
tokenizer >> value; |
6086 |
const int cellId = this->AdditionalCellIds->GetValue(cellI); |
| 2120 |
data->SetValue(i, value); |
6087 |
if(cellId != oldCellId) |
|
|
6088 |
{ |
| 6089 |
ctpData->SetTuple(pointI, cellId, iData); |
| 6090 |
pointI++; |
| 6091 |
oldCellId = cellId; |
| 6092 |
} |
| 2121 |
} |
6093 |
} |
| 2122 |
} |
6094 |
} |
| 2123 |
} |
6095 |
} |
| 2124 |
} |
6096 |
} |
| 2125 |
|
6097 |
} |
| 2126 |
//uniform |
6098 |
else |
| 2127 |
else if(!(temp.find("uniform") == vtkstd::string::npos)) |
6099 |
{ |
| 2128 |
{ |
6100 |
// determine as there's no cells |
| 2129 |
//create an array of uniform values |
6101 |
iData->Delete(); |
| 2130 |
double value1 = 0; |
6102 |
if(acData != NULL) |
| 2131 |
temp.erase(temp.begin(), temp.begin()+temp.find("uniform")+7); |
|
|
| 2132 |
temp.erase(temp.begin()+temp.find(";"), temp.end()); |
| 2133 |
tokenizer.clear(); |
| 2134 |
tokenizer << temp; |
| 2135 |
tokenizer >> value1; |
| 2136 |
data->SetNumberOfValues(this->SizeOfBoundary->value[boundaryIndex]); |
| 2137 |
for(int i = 0; i < this->SizeOfBoundary->value[boundaryIndex]; i++) |
| 2138 |
{ |
| 2139 |
data->SetValue(i, value1); |
| 2140 |
} |
| 2141 |
} |
| 2142 |
|
| 2143 |
//no data |
| 2144 |
else |
| 2145 |
{ |
6103 |
{ |
| 2146 |
int cellId; |
6104 |
acData->Delete(); |
| 2147 |
vtkDataArray * internalData = internalMesh->GetCellData()-> |
|
|
| 2148 |
GetArray(varName.c_str()); |
| 2149 |
data->SetNumberOfValues(this->SizeOfBoundary->value[boundaryIndex]); |
| 2150 |
for(int i = 0; i < this->SizeOfBoundary->value[boundaryIndex]; i++) |
| 2151 |
{ |
| 2152 |
cellId = this->FaceOwner->GetValue(this->StartFace + i); |
| 2153 |
data->SetValue(i, internalData->GetComponent(cellId, 0)); |
| 2154 |
} |
| 2155 |
input->close(); |
| 2156 |
delete input; |
| 2157 |
return data; |
| 2158 |
} |
6105 |
} |
|
|
6106 |
return; |
| 2159 |
} |
6107 |
} |
| 2160 |
//CREATE VECTOR ARRAYS |
6108 |
|
| 2161 |
else if(foamClass == "volVectorField") |
6109 |
vtkFoamBoundaryDict &boundaryDict = *boundaryDictPtr; |
|
|
6110 |
|
| 6111 |
// set boundary values |
| 6112 |
vtkFoamEntry& bEntry = dict.lookup("boundaryField"); |
| 6113 |
if(!bEntry.found()) |
| 2162 |
{ |
6114 |
{ |
| 2163 |
while(temp.find(this->BoundaryNames->value[boundaryIndex]) == |
6115 |
vtkErrorMacro(<< "boundaryField not found in object " << varNameIn |
| 2164 |
vtkstd::string::npos && !input->eof()) |
6116 |
<< " at time = " << this->TimeNames->GetValue(timeState).c_str()); |
|
|
6117 |
iData->Delete(); |
| 6118 |
if(acData != NULL) |
| 2165 |
{ |
6119 |
{ |
| 2166 |
tempStringStruct = this->GetLine(input); |
6120 |
acData->Delete(); |
| 2167 |
temp = tempStringStruct->value; |
|
|
| 2168 |
delete tempStringStruct; |
| 2169 |
} |
6121 |
} |
| 2170 |
if(input->eof()) |
6122 |
if(ctpData != NULL) |
| 2171 |
{ |
6123 |
{ |
| 2172 |
input->close(); |
6124 |
ctpData->Delete(); |
| 2173 |
delete input; |
|
|
| 2174 |
return data; |
| 2175 |
} |
6125 |
} |
| 2176 |
while(temp.find("}") == vtkstd::string::npos && |
6126 |
return; |
| 2177 |
temp.find("value ") == vtkstd::string::npos) |
6127 |
} |
|
|
6128 |
|
| 6129 |
vtkstd::vector<vtkFloatArray *> vDataVector; |
| 6130 |
for(size_t boundaryI = 0, activeBoundaryI = 0; |
| 6131 |
boundaryI < boundaryDict.size(); boundaryI++) |
| 6132 |
{ |
| 6133 |
const vtkStdString &boundaryNameI = boundaryDict[boundaryI].boundaryName; |
| 6134 |
|
| 6135 |
vtkFoamEntry& bEntryI = bEntry.dictionary().lookup(boundaryNameI); |
| 6136 |
if(!bEntryI.found()) |
| 2178 |
{ |
6137 |
{ |
| 2179 |
tempStringStruct = this->GetLine(input); |
6138 |
vtkErrorMacro(<< "boundaryField " << boundaryNameI.c_str() |
| 2180 |
temp = tempStringStruct->value; |
6139 |
<< " not found in object " << varNameIn << " at time = " |
| 2181 |
delete tempStringStruct; //find value |
6140 |
<< this->TimeNames->GetValue(timeState).c_str()); |
|
|
6141 |
iData->Delete(); |
| 6142 |
if(acData != NULL) |
| 6143 |
{ |
| 6144 |
acData->Delete(); |
| 6145 |
} |
| 6146 |
if(ctpData != NULL) |
| 6147 |
{ |
| 6148 |
ctpData->Delete(); |
| 6149 |
} |
| 6150 |
return; |
| 2182 |
} |
6151 |
} |
| 2183 |
//nonuniform |
6152 |
|
| 2184 |
if(!(temp.find("nonuniform") == vtkstd::string::npos)) |
6153 |
if(bEntryI.firstValue().type() != vtkFoamToken::DICTIONARY) |
| 2185 |
{ |
6154 |
{ |
| 2186 |
//create an array |
6155 |
vtkErrorMacro(<< "Type of boundaryField " << boundaryNameI.c_str() |
| 2187 |
tempStringStruct = this->GetLine(input); |
6156 |
<< " is not a subdictionary in object " << varNameIn << " at time = " |
| 2188 |
temp = tempStringStruct->value; |
6157 |
<< this->TimeNames->GetValue(timeState).c_str()); |
| 2189 |
delete tempStringStruct; |
6158 |
iData->Delete(); |
|
|
6159 |
if(acData != NULL) |
| 6160 |
{ |
| 6161 |
acData->Delete(); |
| 6162 |
} |
| 6163 |
if(ctpData != NULL) |
| 6164 |
{ |
| 6165 |
ctpData->Delete(); |
| 6166 |
} |
| 6167 |
return; |
| 6168 |
} |
| 2190 |
|
6169 |
|
| 2191 |
int vectorCount; |
6170 |
const int nFaces = boundaryDict[boundaryI].nFaces; |
| 2192 |
tokenizer.clear(); |
|
|
| 2193 |
tokenizer << temp; |
| 2194 |
tokenizer >> vectorCount; |
| 2195 |
data->SetNumberOfComponents(3); |
| 2196 |
|
6171 |
|
| 2197 |
//binary data |
6172 |
vtkFloatArray* vData = NULL; |
| 2198 |
if(binaryWriteFormat) |
6173 |
bool valueFound = false; |
|
|
6174 |
vtkFoamEntry& vEntry = bEntryI.dictionary().lookup("value"); |
| 6175 |
if(vEntry.found()) // the boundary has a value entry |
| 6176 |
{ |
| 6177 |
vData = this->FillField(&vEntry, nFaces, &io, &fieldType); |
| 6178 |
if(vData == NULL) |
| 2199 |
{ |
6179 |
{ |
| 2200 |
//insert values into the array |
6180 |
iData->Delete(); |
| 2201 |
input->get(); //parenthesis |
6181 |
if(acData != NULL) |
| 2202 |
for(int i = 0; i < vectorCount; i++) |
|
|
| 2203 |
{ |
6182 |
{ |
| 2204 |
input->read((char *) &value, sizeof(double)); |
6183 |
acData->Delete(); |
| 2205 |
data->InsertComponent(i, 0, value); |
|
|
| 2206 |
input->read((char *) &value, sizeof(double)); |
| 2207 |
data->InsertComponent(i, 1, value); |
| 2208 |
input->read((char *) &value, sizeof(double)); |
| 2209 |
data->InsertComponent(i, 2, value); |
| 2210 |
} |
6184 |
} |
|
|
6185 |
if(ctpData != NULL) |
| 6186 |
{ |
| 6187 |
ctpData->Delete(); |
| 6188 |
} |
| 6189 |
return; |
| 2211 |
} |
6190 |
} |
| 2212 |
|
6191 |
valueFound = true; |
| 2213 |
//ascii data |
6192 |
} |
| 2214 |
else |
6193 |
else |
|
|
6194 |
{ |
| 6195 |
// uniformFixedValue B.C. |
| 6196 |
vtkFoamEntry& ufvEntry = bEntryI.dictionary().lookup("type"); |
| 6197 |
if(ufvEntry.found()) |
| 6198 |
{ |
| 6199 |
if(ufvEntry.toString() == "uniformFixedValue") |
| 2215 |
{ |
6200 |
{ |
| 2216 |
//insert values into the array |
6201 |
// the boundary is of uniformFixedValue type |
| 2217 |
tempStringStruct = this->GetLine(input); |
6202 |
vtkFoamEntry& uvEntry = bEntryI.dictionary().lookup("uniformValue"); |
| 2218 |
temp = tempStringStruct->value; |
6203 |
if(uvEntry.found()) // and has a uniformValue entry |
| 2219 |
delete tempStringStruct; //discard ( |
|
|
| 2220 |
for(int i = 0; i < vectorCount; i++) |
| 2221 |
{ |
6204 |
{ |
| 2222 |
tempStringStruct = this->GetLine(input); |
6205 |
vData = this->FillField(&uvEntry, nFaces, &io, &fieldType); |
| 2223 |
temp = tempStringStruct->value; |
6206 |
if(vData == NULL) |
| 2224 |
delete tempStringStruct; |
6207 |
{ |
| 2225 |
|
6208 |
iData->Delete(); |
| 2226 |
//REMOVE BRACKETS |
6209 |
if(acData != NULL) |
| 2227 |
temp.erase(temp.begin()+temp.find("(")); |
6210 |
{ |
| 2228 |
temp.erase(temp.begin()+temp.find(")")); |
6211 |
acData->Delete(); |
| 2229 |
|
6212 |
} |
| 2230 |
//GRAB X,Y,&Z VALUES |
6213 |
if(ctpData != NULL) |
| 2231 |
tokenizer.clear(); |
6214 |
{ |
| 2232 |
tokenizer << temp; |
6215 |
ctpData->Delete(); |
| 2233 |
tokenizer >> value; |
6216 |
} |
| 2234 |
data->InsertComponent(i, 0, value); |
6217 |
return; |
| 2235 |
tokenizer >> value; |
6218 |
} |
| 2236 |
data->InsertComponent(i, 1, value); |
6219 |
valueFound = true; |
| 2237 |
tokenizer >> value; |
|
|
| 2238 |
data->InsertComponent(i, 2, value); |
| 2239 |
} |
6220 |
} |
| 2240 |
} |
6221 |
} |
| 2241 |
} |
6222 |
} |
|
|
6223 |
} |
| 2242 |
|
6224 |
|
| 2243 |
//uniform |
6225 |
const int boundaryStartFace |
| 2244 |
else if(!(temp.find("uniform") == vtkstd::string::npos)) |
6226 |
= boundaryDict[boundaryI].startFace - boundaryDict[0].startFace; |
| 2245 |
{ |
|
|
| 2246 |
//create an array of uniform values |
| 2247 |
double value1 = 0, value2 = 0, value3 = 0; |
| 2248 |
temp.erase(temp.begin(), temp.begin()+temp.find("(")+1); |
| 2249 |
temp.erase(temp.begin()+temp.find(")"), temp.end()); |
| 2250 |
tokenizer.clear(); |
| 2251 |
tokenizer << temp; |
| 2252 |
tokenizer >> value1; |
| 2253 |
tokenizer >> value2; |
| 2254 |
tokenizer >> value3; |
| 2255 |
|
6227 |
|
| 2256 |
data->SetNumberOfComponents(3); |
6228 |
if(!valueFound) // doesn't have a value nor uniformValue entry |
| 2257 |
for(int i = 0; i < this->SizeOfBoundary->value[boundaryIndex]; i++) |
6229 |
{ |
|
|
6230 |
// use patch-internal values as boundary values |
| 6231 |
vData = vtkFloatArray::New(); |
| 6232 |
vData->SetNumberOfComponents(iData->GetNumberOfComponents()); |
| 6233 |
vData->SetNumberOfTuples(nFaces); |
| 6234 |
for(int j = 0; j < nFaces; j++) |
| 2258 |
{ |
6235 |
{ |
| 2259 |
data->InsertComponent(i, 0, value1); |
6236 |
const int cellId = this->FaceOwner->GetValue(boundaryStartFace + j); |
| 2260 |
data->InsertComponent(i, 1, value2); |
6237 |
// in this case GetTuple should be thread-safe accoding to |
| 2261 |
data->InsertComponent(i, 2, value3); |
6238 |
// the FAQ on ParaView Wiki |
|
|
6239 |
vData->SetTuple(j, cellId, iData); |
| 2262 |
} |
6240 |
} |
| 2263 |
} |
6241 |
} |
| 2264 |
|
6242 |
|
| 2265 |
//no data |
6243 |
if(this->CreateCellToPoint && boundaryDict[boundaryI].isPhysicalBoundary) |
| 2266 |
else |
|
|
| 2267 |
{ |
6244 |
{ |
| 2268 |
int cellId; |
6245 |
// set the same value to AllBoundaries |
| 2269 |
vtkDataArray * internalData = internalMesh->GetCellData()-> |
6246 |
for(int faceI = 0; faceI < nFaces; faceI++) |
| 2270 |
GetArray(varName.c_str()); |
|
|
| 2271 |
data->SetNumberOfComponents(3); |
| 2272 |
for(int i = 0; i < this->SizeOfBoundary->value[boundaryIndex]; i++) |
| 2273 |
{ |
6247 |
{ |
| 2274 |
cellId = this->FaceOwner->GetValue(this->StartFace + i); |
6248 |
const int startFace = boundaryDict[boundaryI].allBoundariesStartFace; |
| 2275 |
data->InsertComponent(i, 0, internalData->GetComponent(cellId, 0)); |
6249 |
acData->SetTuple(faceI + startFace, faceI, vData); |
| 2276 |
data->InsertComponent(i, 1, internalData->GetComponent(cellId, 1)); |
|
|
| 2277 |
data->InsertComponent(i, 2, internalData->GetComponent(cellId, 2)); |
| 2278 |
} |
6250 |
} |
| 2279 |
input->close(); |
|
|
| 2280 |
delete input; |
| 2281 |
return data; |
| 2282 |
} |
6251 |
} |
| 2283 |
} |
|
|
| 2284 |
input->close(); |
| 2285 |
delete input; |
| 2286 |
vtkDebugMacro(<<"Boundary data read"); |
| 2287 |
return data; |
| 2288 |
} |
| 2289 |
|
6252 |
|
| 2290 |
// **************************************************************************** |
6253 |
if(boundaryDict[boundaryI].isActive) |
| 2291 |
// Method: vtkOpenFOAMReader::GatherBlocks |
6254 |
{ |
| 2292 |
// |
6255 |
this->AddArrayToFieldData(boundaryMesh->operator[](activeBoundaryI) |
| 2293 |
// Purpose: |
6256 |
->GetCellData(), vData, io.objectName() + dimString); |
| 2294 |
// returns a vector of block names for a specified domain |
|
|
| 2295 |
// |
| 2296 |
// **************************************************************************** |
| 2297 |
stringVector * vtkOpenFOAMReader::GatherBlocks(const char * typeIn, |
| 2298 |
int timeState) |
| 2299 |
{ |
| 2300 |
vtkstd::string type(typeIn); |
| 2301 |
vtkstd::string blockPath = this->PathPrefix->value + |
| 2302 |
this->PolyMeshFacesDir->value[timeState] + |
| 2303 |
"/polyMesh/"+type; |
| 2304 |
vtkstd::vector< vtkstd::string > blocks; |
| 2305 |
stringVector *returnValue = new stringVector; |
| 2306 |
vtkDebugMacro(<<"Get blocks: "<<blockPath.c_str()); |
| 2307 |
|
| 2308 |
ifstream * input = new ifstream(blockPath.c_str(), ios::in VTK_IOS_NOCREATE); |
| 2309 |
//if there is no file return a null vector |
| 2310 |
if(input->fail()) |
| 2311 |
{ |
| 2312 |
input->close(); |
| 2313 |
delete input; |
| 2314 |
returnValue->value = blocks; |
| 2315 |
return returnValue; |
| 2316 |
} |
| 2317 |
|
| 2318 |
vtkstd::string temp; |
| 2319 |
stdString* tempStringStruct; |
| 2320 |
vtkstd::string token; |
| 2321 |
vtksys_ios::stringstream tokenizer; |
| 2322 |
vtkstd::string tempName; |
| 2323 |
|
| 2324 |
//find end of header |
| 2325 |
//while(temp.compare(0,4,"// *",0,4)!=0) |
| 2326 |
while (strcmp(temp.substr(0,4).c_str(), "// *")) |
| 2327 |
{ |
| 2328 |
tempStringStruct = this->GetLine(input); |
| 2329 |
temp = tempStringStruct->value; |
| 2330 |
delete tempStringStruct; |
| 2331 |
} |
| 2332 |
tempStringStruct = this->GetLine(input); |
| 2333 |
temp = tempStringStruct->value; |
| 2334 |
delete tempStringStruct; |
| 2335 |
|
| 2336 |
tempStringStruct = this->GetLine(input); |
| 2337 |
temp = tempStringStruct->value; |
| 2338 |
delete tempStringStruct; //throw out blank line |
| 2339 |
|
| 2340 |
//Number of blocks |
| 2341 |
tokenizer << temp; |
| 2342 |
tokenizer >> this->NumBlocks; |
| 2343 |
blocks.resize(this->NumBlocks); |
| 2344 |
|
| 2345 |
//loop through each block |
| 2346 |
for(int i = 0; i < this->NumBlocks; i++) |
| 2347 |
{ |
| 2348 |
tempStringStruct = this->GetLine(input); |
| 2349 |
temp = tempStringStruct->value; |
| 2350 |
delete tempStringStruct; //throw out blank line |
| 2351 |
|
| 2352 |
//NAME |
| 2353 |
tempStringStruct = this->GetLine(input); |
| 2354 |
temp = tempStringStruct->value; |
| 2355 |
delete tempStringStruct; //name |
| 2356 |
|
| 2357 |
tokenizer.clear(); |
| 2358 |
tokenizer << temp; |
| 2359 |
tokenizer >> tempName; |
| 2360 |
blocks[i] = tempName; |
| 2361 |
//while(temp.compare(0,1,"}",0,1) != 0) |
| 2362 |
while (strcmp(temp.substr(0,1).c_str(), "}")) |
| 2363 |
{ |
| 2364 |
tempStringStruct = this->GetLine(input); |
| 2365 |
temp = tempStringStruct->value; |
| 2366 |
delete tempStringStruct; |
| 2367 |
} |
| 2368 |
} |
| 2369 |
returnValue->value = blocks; |
| 2370 |
input->close(); |
| 2371 |
delete input; |
| 2372 |
return returnValue; |
| 2373 |
} |
| 2374 |
|
6257 |
|
| 2375 |
// **************************************************************************** |
6258 |
if(this->CreateCellToPoint) |
| 2376 |
// Method: vtkOpenFOAMReader::GetBoundaryMesh |
6259 |
{ |
| 2377 |
// |
6260 |
// construct cell-to-point interpolated boundary values. This |
| 2378 |
// Purpose: |
6261 |
// is done independently from allBoundary interpolation so |
| 2379 |
// returns a requested boundary mesh |
6262 |
// that the interpolated values are not affected by |
| 2380 |
// |
6263 |
// neighboring patches especially at patch edges and for |
| 2381 |
// **************************************************************************** |
6264 |
// baffle patches |
| 2382 |
vtkUnstructuredGrid * vtkOpenFOAMReader::GetBoundaryMesh(int timeState, |
6265 |
vtkFloatArray *pData = vtkFloatArray::New(); |
| 2383 |
int boundaryIndex) |
6266 |
pData->SetNumberOfComponents(vData->GetNumberOfComponents()); |
| 2384 |
{ |
6267 |
const int nPoints = boundaryMesh->operator[](activeBoundaryI)-> |
| 2385 |
vtkUnstructuredGrid * boundaryMesh = vtkUnstructuredGrid::New(); |
6268 |
GetPoints()->GetNumberOfPoints(); |
| 2386 |
vtkstd::string boundaryPath = this->PathPrefix->value + |
6269 |
pData->SetNumberOfTuples(nPoints); |
| 2387 |
this->PolyMeshFacesDir->value[timeState] + |
6270 |
this->InterpolateCellToPoint(pData, vData, |
| 2388 |
"/polyMesh/boundary"; |
6271 |
boundaryMesh->operator[](activeBoundaryI), NULL, nPoints); |
| 2389 |
vtkDebugMacro(<<"Create boundary mesh: "<<boundaryPath.c_str()); |
6272 |
#if 0 |
|
|
6273 |
this->AddArrayToFieldData(boundaryMesh->operator[](activeBoundaryI) |
| 6274 |
->GetPointData(), pData, |
| 6275 |
"CellToPoint[" + io.objectName() + "]" + dimString); |
| 6276 |
#else |
| 6277 |
this->AddArrayToFieldData(boundaryMesh->operator[](activeBoundaryI) |
| 6278 |
->GetPointData(), pData, io.objectName() + dimString); |
| 6279 |
#endif |
| 6280 |
pData->Delete(); |
| 6281 |
} |
| 2390 |
|
6282 |
|
| 2391 |
int nFaces; |
6283 |
activeBoundaryI++; |
|
|
6284 |
} |
| 6285 |
vData->Delete(); |
| 6286 |
} |
| 6287 |
iData->Delete(); |
| 2392 |
|
6288 |
|
| 2393 |
ifstream * input = new ifstream(boundaryPath.c_str(), ios::in VTK_IOS_NOCREATE); |
6289 |
if(this->CreateCellToPoint) |
| 2394 |
//return a Null object |
|
|
| 2395 |
if(input->fail()) |
| 2396 |
{ |
6290 |
{ |
| 2397 |
input->close(); |
6291 |
// Create cell-to-point interpolated data for all boundaries and |
| 2398 |
delete input; |
6292 |
// override internal values |
| 2399 |
return boundaryMesh; |
6293 |
vtkFloatArray *bpData = vtkFloatArray::New(); |
| 2400 |
} |
6294 |
bpData->SetNumberOfComponents(acData->GetNumberOfComponents()); |
|
|
6295 |
const int nPoints = this->AllBoundariesPointMap->GetNumberOfTuples(); |
| 6296 |
bpData->SetNumberOfTuples(nPoints); |
| 6297 |
this->InterpolateCellToPoint(bpData, acData, this->AllBoundaries, NULL, |
| 6298 |
nPoints); |
| 6299 |
acData->Delete(); |
| 6300 |
|
| 6301 |
if(ctpData != NULL) |
| 6302 |
{ |
| 6303 |
// set cell-to-pint data for internal mesh |
| 6304 |
for(int pointI = 0; pointI < nPoints; pointI++) |
| 6305 |
{ |
| 6306 |
ctpData->SetTuple(this->AllBoundariesPointMap->GetValue(pointI), pointI, |
| 6307 |
bpData); |
| 6308 |
} |
| 6309 |
#if 0 |
| 6310 |
this->AddArrayToFieldData(internalMesh->GetPointData(), ctpData, |
| 6311 |
"CellToPoint[" + io.objectName() + "]" + dimString); |
| 6312 |
#else |
| 6313 |
this->AddArrayToFieldData(internalMesh->GetPointData(), ctpData, |
| 6314 |
io.objectName() + dimString); |
| 6315 |
#endif |
| 6316 |
ctpData->Delete(); |
| 6317 |
} |
| 2401 |
|
6318 |
|
| 2402 |
vtkstd::string temp; |
6319 |
bpData->Delete(); |
| 2403 |
stdString* tempStringStruct; |
6320 |
} |
| 2404 |
vtkstd::string token; |
6321 |
} |
| 2405 |
vtksys_ios::stringstream tokenizer; |
|
|
| 2406 |
|
6322 |
|
| 2407 |
//find desired mesh entry |
6323 |
//----------------------------------------------------------------------------- |
| 2408 |
while(temp.find(this->BoundaryNames->value[boundaryIndex]) == |
6324 |
// read point field at a timestep |
| 2409 |
vtkstd::string::npos) |
6325 |
void vtkOpenFOAMReader::GetPointFieldAtTimestep( |
|
|
6326 |
vtkUnstructuredGrid* internalMesh, unstructuredGridVector* boundaryMesh, |
| 6327 |
vtkFoamBoundaryDict* boundaryDictPtr, const char* varNameIn, int timeState) |
| 6328 |
{ |
| 6329 |
vtkFoamIOobject io(*this->PathPrefix); |
| 6330 |
vtkFoamDict dict; |
| 6331 |
if(!this->ReadFieldFile(&io, &dict, varNameIn, timeState, |
| 6332 |
this->PointDataArraySelection)) |
| 2410 |
{ |
6333 |
{ |
| 2411 |
tempStringStruct = this->GetLine(input); |
6334 |
return; |
| 2412 |
temp = tempStringStruct->value; |
|
|
| 2413 |
delete tempStringStruct; |
| 2414 |
} |
6335 |
} |
| 2415 |
|
6336 |
|
| 2416 |
//get nFaces |
6337 |
if(io.className().substr(0, 5) != "point") |
| 2417 |
while(temp.find("nFaces") == vtkstd::string::npos) |
|
|
| 2418 |
{ |
6338 |
{ |
| 2419 |
tempStringStruct = this->GetLine(input); |
6339 |
vtkErrorMacro(<< io.objectName().c_str() << " is not a pointField"); |
| 2420 |
temp = tempStringStruct->value; |
6340 |
return; |
| 2421 |
delete tempStringStruct; |
|
|
| 2422 |
} |
6341 |
} |
| 2423 |
temp.erase(temp.begin()+temp.find(";")); //remove ; |
6342 |
|
| 2424 |
tokenizer << temp; |
6343 |
vtkFoamEntry &iEntry = dict.lookup("internalField"); |
| 2425 |
//while(tokenizer >> token); |
6344 |
if(!iEntry.found()) |
| 2426 |
while(!tokenizer.eof()) |
|
|
| 2427 |
{ |
6345 |
{ |
| 2428 |
tokenizer >> token; |
6346 |
vtkErrorMacro(<<"internalField not found in " << io.fileName().c_str()); |
|
|
6347 |
return; |
| 2429 |
} |
6348 |
} |
| 2430 |
tokenizer.clear(); |
|
|
| 2431 |
tokenizer << token; |
| 2432 |
tokenizer >> nFaces; |
| 2433 |
|
| 2434 |
//get startface |
| 2435 |
tempStringStruct = this->GetLine(input); |
| 2436 |
temp = tempStringStruct->value; |
| 2437 |
delete tempStringStruct; |
| 2438 |
|
6349 |
|
| 2439 |
//look for "startFaces" |
6350 |
if(iEntry.firstValue().type() == vtkFoamToken::EMPTYLIST) |
| 2440 |
while(temp.find("startFace") == vtkstd::string::npos) |
|
|
| 2441 |
{ |
6351 |
{ |
| 2442 |
tempStringStruct = this->GetLine(input); |
6352 |
// if there's no cell there shouldn't be any boundary faces either |
| 2443 |
temp = tempStringStruct->value; |
6353 |
if(this->NumPoints > 0) |
| 2444 |
delete tempStringStruct; |
6354 |
{ |
|
|
6355 |
vtkErrorMacro(<<"internalField of " << io.objectName().c_str() |
| 6356 |
<< " is empty"); |
| 6357 |
} |
| 6358 |
return; |
| 2445 |
} |
6359 |
} |
| 2446 |
temp.erase(temp.begin()+temp.find(";")); //remove ; |
6360 |
|
| 2447 |
tokenizer.clear(); |
6361 |
vtkStdString fieldType = io.className().substr(5, vtkStdString::npos); |
| 2448 |
tokenizer << temp; |
6362 |
vtkFloatArray *iData = this->FillField(&iEntry, this->NumPoints, &io, |
| 2449 |
//while(tokenizer >> token); |
6363 |
&fieldType); |
| 2450 |
while(!tokenizer.eof()) |
6364 |
if(iData == NULL) |
| 2451 |
{ |
6365 |
{ |
| 2452 |
tokenizer >> token; |
6366 |
return; |
| 2453 |
} |
6367 |
} |
| 2454 |
tokenizer.clear(); |
|
|
| 2455 |
tokenizer << token; |
| 2456 |
tokenizer >> this->StartFace; |
| 2457 |
|
6368 |
|
| 2458 |
//Create the mesh |
6369 |
vtkStdString dimString; |
| 2459 |
int j, k; |
6370 |
this->ConstructDimensions(&dimString, &dict); |
| 2460 |
vtkTriangle * triangle; |
|
|
| 2461 |
vtkQuad * quad; |
| 2462 |
vtkPolygon * polygon; |
| 2463 |
int endFace = this->StartFace + nFaces; |
| 2464 |
//loop through each face |
| 2465 |
for(j = this->StartFace; j < endFace; j++) |
| 2466 |
{ |
| 2467 |
|
6371 |
|
| 2468 |
//triangle |
6372 |
// AdditionalCellPoints is NULL if creation of InternalMesh had been skipped |
| 2469 |
if(this->FacePoints->value[j].size() == 3) |
6373 |
if(this->AdditionalCellPoints != NULL) |
| 2470 |
{ |
6374 |
{ |
| 2471 |
triangle = vtkTriangle::New(); |
6375 |
// point-to-cell interpolation to additional cell centroidal points |
| 2472 |
for(k = 0; k < 3; k++) |
6376 |
// for decomposed cells |
|
|
6377 |
const int nAdditionalPoints = this->AdditionalCellPoints->size(); |
| 6378 |
const int nComponents = iData->GetNumberOfComponents(); |
| 6379 |
iData->Resize(this->NumPoints + nAdditionalPoints); |
| 6380 |
for(int i = 0; i < nAdditionalPoints; i++) |
| 6381 |
{ |
| 6382 |
vtkIntArray *acp = this->AdditionalCellPoints->operator[](i); |
| 6383 |
int nPoints = acp->GetDataSize(); |
| 6384 |
float interpolatedValue[9]; |
| 6385 |
for(int k = 0; k < nComponents; k++) |
| 6386 |
{ |
| 6387 |
interpolatedValue[k] = 0.0F; |
| 6388 |
} |
| 6389 |
for(int j = 0; j < nPoints; j++) |
| 6390 |
{ |
| 6391 |
const float *tuple = iData->GetPointer(nComponents * acp->GetValue(j)); |
| 6392 |
for(int k = 0; k < nComponents; k++) |
| 6393 |
{ |
| 6394 |
interpolatedValue[k] += tuple[k]; |
| 6395 |
} |
| 6396 |
} |
| 6397 |
const float weight = 1.0F / static_cast<float>(nPoints); |
| 6398 |
for(int k = 0; k < nComponents; k++) |
| 2473 |
{ |
6399 |
{ |
| 2474 |
triangle->GetPointIds()->SetId(k, this->FacePoints->value[j][k]); |
6400 |
interpolatedValue[k] *= weight; |
| 2475 |
} |
6401 |
} |
| 2476 |
boundaryMesh->InsertNextCell(triangle->GetCellType(), |
6402 |
iData->InsertTuple(this->NumPoints + i, interpolatedValue); |
| 2477 |
triangle->GetPointIds()); |
|
|
| 2478 |
triangle->Delete(); |
| 2479 |
} |
6403 |
} |
|
|
6404 |
} |
| 2480 |
|
6405 |
|
| 2481 |
//quad |
6406 |
if(iData->GetSize() > 0) |
| 2482 |
else if(this->FacePoints->value[j].size() == 4) |
6407 |
{ |
|
|
6408 |
// Add field only if internal Mesh exists (skip if not selected). |
| 6409 |
// Note we still need to read internalField even if internal mesh is |
| 6410 |
// not selected, since boundaries without value entries may refer to |
| 6411 |
// the internalField. |
| 6412 |
if(internalMesh != NULL) |
| 2483 |
{ |
6413 |
{ |
| 2484 |
quad = vtkQuad::New(); |
6414 |
// set data to internal mesh |
| 2485 |
for(k = 0; k < 4; k++) |
6415 |
this->AddArrayToFieldData(internalMesh->GetPointData(), iData, |
| 2486 |
{ |
6416 |
io.objectName() + dimString); |
| 2487 |
quad->GetPointIds()->SetId(k, this->FacePoints->value[j][k]); |
|
|
| 2488 |
} |
| 2489 |
boundaryMesh->InsertNextCell(quad->GetCellType(), |
| 2490 |
quad->GetPointIds()); |
| 2491 |
quad->Delete(); |
| 2492 |
} |
6417 |
} |
|
|
6418 |
} |
| 6419 |
else |
| 6420 |
{ |
| 6421 |
// determine as there's no points |
| 6422 |
iData->Delete(); |
| 6423 |
return; |
| 6424 |
} |
| 2493 |
|
6425 |
|
| 2494 |
//polygon |
6426 |
// use patch-internal values as boundary values |
| 2495 |
else |
6427 |
vtkFoamBoundaryDict &boundaryDict = *boundaryDictPtr; |
|
|
6428 |
for(size_t boundaryI = 0, activeBoundaryI = 0; |
| 6429 |
boundaryI < boundaryDict.size(); boundaryI++) |
| 6430 |
{ |
| 6431 |
if(boundaryDict[boundaryI].isActive) |
| 2496 |
{ |
6432 |
{ |
| 2497 |
polygon = vtkPolygon::New(); |
6433 |
vtkFloatArray *vData = vtkFloatArray::New(); |
| 2498 |
for(k = 0; k < (int)this->FacePoints->value[j].size(); k++) |
6434 |
vtkIntArray& bpMap = *this->BoundaryPointMap->operator[](activeBoundaryI); |
|
|
6435 |
const int nPoints = bpMap.GetNumberOfTuples(); |
| 6436 |
vData->SetNumberOfComponents(iData->GetNumberOfComponents()); |
| 6437 |
vData->SetNumberOfTuples(nPoints); |
| 6438 |
for(int j = 0; j < nPoints; j++) |
| 2499 |
{ |
6439 |
{ |
| 2500 |
polygon->GetPointIds()->InsertId(k, this->FacePoints->value[j][k]); |
6440 |
vData->SetTuple(j, bpMap.GetValue(j), iData); |
| 2501 |
} |
6441 |
} |
| 2502 |
boundaryMesh->InsertNextCell(polygon->GetCellType(), |
6442 |
this->AddArrayToFieldData(boundaryMesh->operator[](activeBoundaryI) |
| 2503 |
polygon->GetPointIds()); |
6443 |
->GetPointData(), vData, io.objectName() + dimString); |
| 2504 |
polygon->Delete(); |
6444 |
vData->Delete(); |
|
|
6445 |
activeBoundaryI++; |
| 2505 |
} |
6446 |
} |
| 2506 |
} |
6447 |
} |
| 2507 |
|
6448 |
iData->Delete(); |
| 2508 |
//set points for boundary |
|
|
| 2509 |
boundaryMesh->SetPoints(this->Points); |
| 2510 |
//add size of mesh |
| 2511 |
this->SizeOfBoundary->value.push_back(boundaryMesh->GetNumberOfCells()); |
| 2512 |
input->close(); |
| 2513 |
delete input; |
| 2514 |
vtkDebugMacro(<<"Boundary mesh created"); |
| 2515 |
return boundaryMesh; |
| 2516 |
} |
6449 |
} |
| 2517 |
|
6450 |
|
| 2518 |
// **************************************************************************** |
6451 |
//----------------------------------------------------------------------------- |
| 2519 |
// Method: vtkOpenFOAMReader::GetPointZoneMesh |
6452 |
vtkPolyData* vtkOpenFOAMReader::MakeLagrangianMesh(int timeState, |
| 2520 |
// |
6453 |
const vtkStdString &lagrangianPath) |
| 2521 |
// Purpose: |
|
|
| 2522 |
// returns a requested point zone mesh |
| 2523 |
// |
| 2524 |
// **************************************************************************** |
| 2525 |
vtkUnstructuredGrid * vtkOpenFOAMReader::GetPointZoneMesh(int timeState, |
| 2526 |
int pointZoneIndex) |
| 2527 |
{ |
6454 |
{ |
| 2528 |
vtkUnstructuredGrid * pointZoneMesh = vtkUnstructuredGrid::New(); |
6455 |
vtkStdString positionsPath = *this->PathPrefix |
| 2529 |
vtkstd::string pointZonesPath = this->PathPrefix->value[timeState]+ |
6456 |
+ this->TimeNames->GetValue(timeState) + "/" + lagrangianPath |
| 2530 |
"/polyMesh/pointZones"; |
6457 |
+ "/positions"; |
| 2531 |
vtkDebugMacro(<<"Create point zone mesh: "<<pointZonesPath.c_str()); |
|
|
| 2532 |
|
6458 |
|
| 2533 |
vtkstd::string temp; |
6459 |
vtkFoamIOobject io(*this->PathPrefix); |
| 2534 |
stdString* tempStringStruct; |
6460 |
if(!(io.open(positionsPath) || io.open(positionsPath + ".gz"))) |
| 2535 |
bool binaryWriteFormat; |
|
|
| 2536 |
ifstream * input = new ifstream(pointZonesPath.c_str(), ios::in VTK_IOS_NOCREATE); |
| 2537 |
//make sure file exists |
| 2538 |
if(input->fail()) |
| 2539 |
{ |
6461 |
{ |
| 2540 |
input->close(); |
6462 |
// if positions doesn't exist we simply return without issuing an error |
| 2541 |
delete input; |
6463 |
return NULL; |
| 2542 |
return pointZoneMesh; |
|
|
| 2543 |
} |
6464 |
} |
| 2544 |
|
6465 |
|
| 2545 |
//determine if file is binary or ascii |
6466 |
// tell the IO object if the file is in OF 1.3 binary |
| 2546 |
while(temp.find("format") == vtkstd::string::npos) |
6467 |
// lagrangian/positions format |
| 2547 |
{ |
6468 |
io.setIs13Positions(this->PositionsIsIn13Format != 0); |
| 2548 |
tempStringStruct = this->GetLine(input); |
|
|
| 2549 |
temp = tempStringStruct->value; |
| 2550 |
delete tempStringStruct; |
| 2551 |
} |
| 2552 |
input->close(); |
| 2553 |
|
6469 |
|
| 2554 |
//reopen file in correct format |
6470 |
vtkFoamDict dict; |
| 2555 |
if(temp.find("binary") != vtkstd::string::npos) |
6471 |
if(!dict.read(io)) |
| 2556 |
{ |
6472 |
{ |
| 2557 |
#ifdef _WIN32 |
6473 |
vtkErrorMacro(<<"Error reading line " << io.lineNumber() |
| 2558 |
input->open(pointZonesPath.c_str(), ios::binary | ios::in VTK_IOS_NOCREATE); |
6474 |
<< " of " << io.fileName().c_str() << ": " << io.error().c_str()); |
| 2559 |
#else |
6475 |
return NULL; |
| 2560 |
input->open(pointZonesPath.c_str(), ios::in VTK_IOS_NOCREATE); |
|
|
| 2561 |
#endif |
| 2562 |
binaryWriteFormat = true; |
| 2563 |
} |
6476 |
} |
| 2564 |
else |
6477 |
if(dict.type() != vtkFoamToken::VECTORLIST) |
| 2565 |
{ |
6478 |
{ |
| 2566 |
input->open(pointZonesPath.c_str(),ios::in); |
6479 |
vtkErrorMacro(<<"The file type of " << io.fileName().c_str() |
| 2567 |
binaryWriteFormat = false; |
6480 |
<< " is not a vectorList"); |
|
|
6481 |
return NULL; |
| 2568 |
} |
6482 |
} |
| 2569 |
|
6483 |
|
| 2570 |
vtkstd::string token; |
6484 |
vtkFloatArray *pointArray = reinterpret_cast<vtkFloatArray *>(dict.ptr()); |
| 2571 |
vtksys_ios::stringstream tokenizer; |
6485 |
const int nParticles = pointArray->GetNumberOfTuples(); |
| 2572 |
vtkVertex * pointCell; |
|
|
| 2573 |
int tempElement; |
| 2574 |
vtkstd::vector< vtkstd::vector < int > > tempElementZones; |
| 2575 |
int numElement; |
| 2576 |
|
| 2577 |
//find desired mesh entry |
| 2578 |
while(temp.find(this->PointZoneNames->value[pointZoneIndex]) == |
| 2579 |
vtkstd::string::npos) |
| 2580 |
{ |
| 2581 |
tempStringStruct = this->GetLine(input); |
| 2582 |
temp = tempStringStruct->value; |
| 2583 |
delete tempStringStruct; |
| 2584 |
} |
| 2585 |
tempStringStruct = this->GetLine(input); |
| 2586 |
temp = tempStringStruct->value; |
| 2587 |
delete tempStringStruct;//throw out { |
| 2588 |
|
| 2589 |
tempStringStruct = this->GetLine(input); |
| 2590 |
temp = tempStringStruct->value; |
| 2591 |
delete tempStringStruct;//type |
| 2592 |
|
| 2593 |
tempStringStruct = this->GetLine(input); |
| 2594 |
temp = tempStringStruct->value; |
| 2595 |
delete tempStringStruct;//label |
| 2596 |
|
| 2597 |
tempStringStruct = this->GetLine(input); |
| 2598 |
temp = tempStringStruct->value; |
| 2599 |
delete tempStringStruct;//number of elements or { |
| 2600 |
|
| 2601 |
//number of elements |
| 2602 |
if(temp.find("}") == vtkstd::string::npos) |
| 2603 |
{ |
| 2604 |
tokenizer << temp; |
| 2605 |
tokenizer >> numElement; |
| 2606 |
if(numElement == 0) |
| 2607 |
{ |
| 2608 |
input->close(); |
| 2609 |
delete input; |
| 2610 |
return NULL; |
| 2611 |
} |
| 2612 |
|
6486 |
|
| 2613 |
//binary data |
6487 |
// instantiate the points class |
| 2614 |
if(binaryWriteFormat) |
6488 |
vtkPoints *points = vtkPoints::New(); |
| 2615 |
{ |
6489 |
points->SetData(pointArray); |
| 2616 |
input->get(); //parenthesis |
6490 |
pointArray->Delete(); |
| 2617 |
for(int j = 0; j < numElement; j++) |
6491 |
|
| 2618 |
{ |
6492 |
// create lagrangian mesh |
| 2619 |
input->read((char *) &tempElement, sizeof(int)); |
6493 |
vtkPolyData* lagrangianMesh = vtkPolyData::New(); |
| 2620 |
pointCell = vtkVertex::New(); |
6494 |
lagrangianMesh->Allocate(nParticles); |
| 2621 |
pointCell->GetPointIds()->SetId(0,tempElement); |
6495 |
for(vtkIdType i = 0; i < nParticles; i++) |
| 2622 |
pointZoneMesh->InsertNextCell(pointCell->GetCellType(), |
6496 |
{ |
| 2623 |
pointCell->GetPointIds()); |
6497 |
lagrangianMesh->InsertNextCell(VTK_VERTEX, 1, &i); |
| 2624 |
pointCell->Delete(); |
6498 |
} |
| 2625 |
} |
6499 |
lagrangianMesh->SetPoints(points); |
| 2626 |
} |
6500 |
points->Delete(); |
|
|
6501 |
this->SetDataObjectName(lagrangianMesh, lagrangianPath.c_str()); |
| 2627 |
|
6502 |
|
| 2628 |
//ascii data |
6503 |
return lagrangianMesh; |
| 2629 |
else |
6504 |
} |
| 2630 |
{ |
|
|
| 2631 |
tempStringStruct = this->GetLine(input); |
| 2632 |
temp = tempStringStruct->value; |
| 2633 |
delete tempStringStruct;//THROW OUT ( |
| 2634 |
|
6505 |
|
| 2635 |
//GET EACH ELEMENT & ADD TO VECTOR |
6506 |
//----------------------------------------------------------------------------- |
| 2636 |
for(int j = 0; j < numElement; j++) |
6507 |
void vtkOpenFOAMReader::GetLagrangianFieldAtTimestep( |
| 2637 |
{ |
6508 |
vtkPolyData* lagrangianMesh, const char* varNameIn, int timeState, |
| 2638 |
tempStringStruct = this->GetLine(input); |
6509 |
const vtkStdString &lagrangianPath) |
| 2639 |
temp = tempStringStruct->value; |
6510 |
{ |
| 2640 |
delete tempStringStruct; |
6511 |
vtkStdString varPath = *this->PathPrefix |
|
|
6512 |
+ this->TimeNames->GetValue(timeState) + "/" + lagrangianPath + "/" |
| 6513 |
+ vtkStdString(varNameIn); |
| 6514 |
|
| 6515 |
// open the file |
| 6516 |
vtkFoamIOobject io(*this->PathPrefix); |
| 6517 |
if(!io.open(varPath)) |
| 6518 |
{ |
| 6519 |
// if the field file doesn't exist we simply return without issuing an error |
| 6520 |
// as a simple way of supporting multi-region lagrangians |
| 6521 |
#if 0 |
| 6522 |
vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": " |
| 6523 |
<< io.error().c_str()); |
| 6524 |
#endif |
| 6525 |
return; |
| 6526 |
} |
| 2641 |
|
6527 |
|
| 2642 |
tokenizer.clear(); |
6528 |
// if the variable is disabled on selection panel then skip it |
| 2643 |
tokenizer << temp; |
6529 |
vtkStdString selectionName = io.objectName(); |
| 2644 |
tokenizer >> tempElement; |
6530 |
if(this->LagrangianDataArraySelection->ArrayExists(selectionName.c_str()) |
| 2645 |
pointCell = vtkVertex::New(); |
6531 |
&& !this->LagrangianDataArraySelection |
| 2646 |
pointCell->GetPointIds()->SetId(0,tempElement); |
6532 |
->ArrayIsEnabled(selectionName.c_str())) |
| 2647 |
pointZoneMesh->InsertNextCell(pointCell->GetCellType(), |
6533 |
{ |
| 2648 |
pointCell->GetPointIds()); |
6534 |
return; |
| 2649 |
pointCell->Delete(); |
|
|
| 2650 |
} |
| 2651 |
} |
| 2652 |
} |
6535 |
} |
| 2653 |
|
6536 |
|
| 2654 |
//there is no entry |
6537 |
// read the field file into dictionary |
| 2655 |
else |
6538 |
vtkFoamDict dict; |
|
|
6539 |
if(!dict.read(io)) |
| 2656 |
{ |
6540 |
{ |
| 2657 |
input->close(); |
6541 |
vtkErrorMacro(<<"Error reading line " << io.lineNumber() |
| 2658 |
delete input; |
6542 |
<< " of " << io.fileName().c_str() << ": " << io.error().c_str()); |
| 2659 |
return NULL; |
6543 |
return; |
| 2660 |
} |
6544 |
} |
| 2661 |
//set point zone points |
6545 |
|
| 2662 |
pointZoneMesh->SetPoints(Points); |
6546 |
// set lagrangian values |
| 2663 |
input->close(); |
6547 |
if(dict.type() != vtkFoamToken::SCALARLIST |
| 2664 |
delete input; |
6548 |
&& dict.type() != vtkFoamToken::VECTORLIST) |
| 2665 |
vtkDebugMacro(<<"Point zone mesh created"); |
6549 |
{ |
| 2666 |
return pointZoneMesh; |
6550 |
vtkErrorMacro(<< io.fileName().c_str() |
|
|
6551 |
<< ": Unsupported lagrangian field type " << io.className().c_str()); |
| 6552 |
return; |
| 6553 |
} |
| 6554 |
|
| 6555 |
vtkFloatArray* lData = reinterpret_cast<vtkFloatArray *>(dict.ptr()); |
| 6556 |
|
| 6557 |
// GetNumberOfTuples() works for both scalar and vector |
| 6558 |
const int nParticles = lData->GetNumberOfTuples(); |
| 6559 |
if(nParticles != lagrangianMesh->GetNumberOfCells()) |
| 6560 |
{ |
| 6561 |
vtkErrorMacro(<< io.fileName().c_str() |
| 6562 |
<<": Sizes of lagrangian mesh and field don't match: mesh = " |
| 6563 |
<< lagrangianMesh->GetNumberOfCells() << ", field = " << nParticles); |
| 6564 |
lData->Delete(); |
| 6565 |
return; |
| 6566 |
} |
| 6567 |
|
| 6568 |
this->AddArrayToFieldData(lagrangianMesh->GetCellData(), lData, |
| 6569 |
selectionName); |
| 6570 |
if(this->CreateCellToPoint) |
| 6571 |
{ |
| 6572 |
#if 0 |
| 6573 |
// have to use SetArray() since a vtkFloatArray can't be ShallowCopy()-ed |
| 6574 |
vtkFloatArray *lpData = vtkFloatArray::New(); |
| 6575 |
lpData->SetNumberOfComponents(lData->GetNumberOfComponents()); |
| 6576 |
lpData->SetArray(lData->GetPointer(0), lData->GetMaxId() + 1, 1); |
| 6577 |
this->AddArrayToFieldData(lagrangianMesh->GetPointData(), lpData, |
| 6578 |
"CellToPoint[" + selectionName + "]"); |
| 6579 |
lpData->Delete(); |
| 6580 |
#else |
| 6581 |
this->AddArrayToFieldData(lagrangianMesh->GetPointData(), lData, |
| 6582 |
selectionName); |
| 6583 |
#endif |
| 6584 |
} |
| 6585 |
lData->Delete(); |
| 6586 |
|
| 6587 |
return; |
| 2667 |
} |
6588 |
} |
| 2668 |
|
6589 |
|
| 2669 |
// **************************************************************************** |
6590 |
//----------------------------------------------------------------------------- |
| 2670 |
// Method: vtkOpenFOAMReader::GetFaceZoneMesh |
6591 |
// returns a dictionary of block names for a specified domain |
| 2671 |
// |
6592 |
vtkOpenFOAMReader::vtkFoamDict* vtkOpenFOAMReader::GatherBlocks( |
| 2672 |
// Purpose: |
6593 |
const char* typeIn, int timeState, bool mustRead) |
| 2673 |
// returns a requested face zone mesh |
|
|
| 2674 |
// |
| 2675 |
// **************************************************************************** |
| 2676 |
vtkUnstructuredGrid * vtkOpenFOAMReader::GetFaceZoneMesh(int timeState, |
| 2677 |
int faceZoneIndex) |
| 2678 |
{ |
6594 |
{ |
| 2679 |
vtkUnstructuredGrid * faceZoneMesh = vtkUnstructuredGrid::New(); |
6595 |
vtkStdString type(typeIn); |
| 2680 |
vtkstd::string faceZonesPath = this->PathPrefix->value + |
6596 |
vtkStdString blockPath = *this->PathPrefix |
| 2681 |
this->PolyMeshFacesDir->value[timeState] + |
6597 |
+ this->PolyMeshFacesDir->GetValue(timeState) + "/" + type; |
| 2682 |
"/polyMesh/faceZones"; |
|
|
| 2683 |
vtkDebugMacro(<<"Create face zone mesh: "<<faceZonesPath.c_str()); |
| 2684 |
|
6598 |
|
| 2685 |
vtkstd::string temp; |
6599 |
vtkFoamIOobject io(*this->PathPrefix); |
| 2686 |
stdString* tempStringStruct; |
6600 |
if(!(io.open(blockPath) || io.open(blockPath + ".gz"))) |
| 2687 |
bool binaryWriteFormat; |
|
|
| 2688 |
ifstream * input = new ifstream(faceZonesPath.c_str(), ios::in VTK_IOS_NOCREATE); |
| 2689 |
//make sure file exists |
| 2690 |
if(input->fail()) |
| 2691 |
{ |
6601 |
{ |
| 2692 |
input->close(); |
6602 |
if(mustRead) |
| 2693 |
delete input; |
6603 |
{ |
| 2694 |
return faceZoneMesh; |
6604 |
vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": " |
|
|
6605 |
<< io.error().c_str()); |
| 6606 |
} |
| 6607 |
return NULL; |
| 2695 |
} |
6608 |
} |
| 2696 |
|
6609 |
|
| 2697 |
//determine if file is binary or ascii |
6610 |
vtkFoamDict* dictPtr = new vtkFoamDict; |
| 2698 |
while(temp.find("format") == vtkstd::string::npos) |
6611 |
vtkFoamDict& dict = *dictPtr; |
| 2699 |
{ |
6612 |
if(!dict.read(io)) |
| 2700 |
tempStringStruct = this->GetLine(input); |
6613 |
{ |
| 2701 |
temp = tempStringStruct->value; |
6614 |
vtkErrorMacro(<<"Error reading line " << io.lineNumber() |
| 2702 |
delete tempStringStruct; |
6615 |
<< " of " << io.fileName().c_str() << ": " << io.error().c_str()); |
|
|
6616 |
delete dictPtr; |
| 6617 |
return NULL; |
| 2703 |
} |
6618 |
} |
| 2704 |
input->close(); |
6619 |
if(dict.type() != vtkFoamToken::DICTIONARY) |
| 2705 |
|
|
|
| 2706 |
//reopen file in correct format |
| 2707 |
if(temp.find("binary") != vtkstd::string::npos) |
| 2708 |
{ |
6620 |
{ |
| 2709 |
#ifdef _WIN32 |
6621 |
vtkErrorMacro(<<"The file type of " << io.fileName().c_str() |
| 2710 |
input->open(faceZonesPath.c_str(), ios::binary | ios::in VTK_IOS_NOCREATE); |
6622 |
<< " is not a dictionary"); |
| 2711 |
#else |
6623 |
delete dictPtr; |
| 2712 |
input->open(faceZonesPath.c_str(), ios::in); |
6624 |
return NULL; |
| 2713 |
#endif |
|
|
| 2714 |
binaryWriteFormat = true; |
| 2715 |
} |
6625 |
} |
| 2716 |
else |
6626 |
return dictPtr; |
|
|
6627 |
} |
| 6628 |
|
| 6629 |
//----------------------------------------------------------------------------- |
| 6630 |
// returns a requested point zone mesh |
| 6631 |
bool vtkOpenFOAMReader::GetPointZoneMesh(unstructuredGridVector* pointZoneMesh, |
| 6632 |
vtkPoints* points, int timeState) |
| 6633 |
{ |
| 6634 |
vtkDebugMacro(<<"Create point zone mesh"); |
| 6635 |
|
| 6636 |
vtkFoamDict* pointZoneDictPtr |
| 6637 |
= this->GatherBlocks("polyMesh/pointZones", timeState, false); |
| 6638 |
|
| 6639 |
if(pointZoneDictPtr == NULL) |
| 2717 |
{ |
6640 |
{ |
| 2718 |
input->open(faceZonesPath.c_str(),ios::in); |
6641 |
// not an error |
| 2719 |
binaryWriteFormat = false; |
6642 |
return true; |
| 2720 |
} |
6643 |
} |
| 2721 |
|
6644 |
|
| 2722 |
vtkstd::string token; |
6645 |
vtkFoamDict& pointZoneDict = *pointZoneDictPtr; |
| 2723 |
vtksys_ios::stringstream tokenizer; |
6646 |
size_t nPointZones = pointZoneDict.size(); |
| 2724 |
vtkstd::vector< int > faceZone; |
|
|
| 2725 |
int tempElement; |
| 2726 |
vtkstd::vector< vtkstd::vector < int > > tempElementZones; |
| 2727 |
int numElement; |
| 2728 |
|
6647 |
|
| 2729 |
//find desired mesh entry |
6648 |
for(size_t i = 0; i < nPointZones; i++) |
| 2730 |
while(temp.find(this->FaceZoneNames->value[faceZoneIndex]) == |
|
|
| 2731 |
vtkstd::string::npos) |
| 2732 |
{ |
6649 |
{ |
| 2733 |
tempStringStruct = this->GetLine(input); |
6650 |
// look up point labels |
| 2734 |
temp = tempStringStruct->value; |
6651 |
vtkFoamDict& dict = pointZoneDict.entry(i).dictionary(); |
| 2735 |
delete tempStringStruct; |
6652 |
vtkFoamEntry& pointLabelsEntry = dict.lookup("pointLabels"); |
|
|
6653 |
if(!pointLabelsEntry.found()) |
| 6654 |
{ |
| 6655 |
delete pointZoneDictPtr; |
| 6656 |
vtkErrorMacro(<<"pointLabels not found in pointZones"); |
| 6657 |
return false; |
| 6658 |
} |
| 6659 |
|
| 6660 |
// allocate an empty mesh if the list is empty |
| 6661 |
if(pointLabelsEntry.firstValue().type() == vtkFoamToken::EMPTYLIST) |
| 6662 |
{ |
| 6663 |
vtkUnstructuredGrid *pzm = vtkUnstructuredGrid::New(); |
| 6664 |
pointZoneMesh->push_back(pzm); |
| 6665 |
// set name |
| 6666 |
this->SetDataObjectName(pzm, pointZoneDict.entry(i).keyword()); |
| 6667 |
continue; |
| 6668 |
} |
| 6669 |
|
| 6670 |
if(pointLabelsEntry.firstValue().type() != vtkFoamToken::LABELLIST) |
| 6671 |
{ |
| 6672 |
delete pointZoneDictPtr; |
| 6673 |
vtkErrorMacro(<<"pointLabels not of type labelList: type = " |
| 6674 |
<< pointLabelsEntry.firstValue().type()); |
| 6675 |
return false; |
| 6676 |
} |
| 6677 |
|
| 6678 |
vtkIntArray &labels = pointLabelsEntry.labelList(); |
| 6679 |
|
| 6680 |
int nPoints = labels.GetNumberOfTuples(); |
| 6681 |
if(nPoints > this->NumPoints) |
| 6682 |
{ |
| 6683 |
vtkErrorMacro(<<"The length of pointLabels " << nPoints |
| 6684 |
<< " for pointZone " << pointZoneDict.entry(i).keyword().c_str() |
| 6685 |
<< " exceeds the number of points " << this->NumPoints); |
| 6686 |
delete pointZoneDictPtr; |
| 6687 |
return false; |
| 6688 |
} |
| 6689 |
|
| 6690 |
// allocate new grid: we do not use resize() beforehand since it |
| 6691 |
// could lead to undefined pointer if we return by error |
| 6692 |
vtkUnstructuredGrid *pzm = vtkUnstructuredGrid::New(); |
| 6693 |
pointZoneMesh->push_back(pzm); |
| 6694 |
|
| 6695 |
// set pointZone size |
| 6696 |
pzm->Allocate(nPoints); |
| 6697 |
|
| 6698 |
// insert points |
| 6699 |
for(int j = 0; j < nPoints; j++) |
| 6700 |
{ |
| 6701 |
vtkIdType pointLabel = labels.GetValue(j); // must be vtkIdType |
| 6702 |
if(pointLabel >= this->NumPoints) |
| 6703 |
{ |
| 6704 |
vtkWarningMacro(<<"pointLabels id " << pointLabel |
| 6705 |
<< " exceeds the number of points " << this->NumPoints); |
| 6706 |
pzm->InsertNextCell(VTK_EMPTY_CELL, 0, &pointLabel); |
| 6707 |
continue; |
| 6708 |
} |
| 6709 |
pzm->InsertNextCell(VTK_VERTEX, 1, &pointLabel); |
| 6710 |
} |
| 6711 |
pzm->SetPoints(points); |
| 6712 |
|
| 6713 |
// set name |
| 6714 |
this->SetDataObjectName(pzm, pointZoneDict.entry(i).keyword()); |
| 2736 |
} |
6715 |
} |
| 2737 |
|
6716 |
|
| 2738 |
tempStringStruct = this->GetLine(input); |
6717 |
delete pointZoneDictPtr; |
| 2739 |
temp = tempStringStruct->value; |
6718 |
|
| 2740 |
delete tempStringStruct;//throw out { |
6719 |
vtkDebugMacro(<<"Point zone mesh created"); |
|
|
6720 |
return true; |
| 6721 |
} |
| 6722 |
|
| 6723 |
//----------------------------------------------------------------------------- |
| 6724 |
// returns a requested face zone mesh |
| 6725 |
bool vtkOpenFOAMReader::GetFaceZoneMesh( |
| 6726 |
unstructuredGridVector *faceZoneMesh, const intVectorVector *facesPoints, |
| 6727 |
vtkPoints* points, int timeState) |
| 6728 |
{ |
| 6729 |
vtkDebugMacro(<<"Create face zone mesh"); |
| 2741 |
|
6730 |
|
| 2742 |
tempStringStruct = this->GetLine(input); |
6731 |
vtkFoamDict* faceZoneDictPtr |
| 2743 |
temp = tempStringStruct->value; |
6732 |
= this->GatherBlocks("polyMesh/faceZones", timeState, false); |
| 2744 |
delete tempStringStruct;//type |
|
|
| 2745 |
|
6733 |
|
| 2746 |
tempStringStruct = this->GetLine(input); |
6734 |
if(faceZoneDictPtr == NULL) |
| 2747 |
temp = tempStringStruct->value; |
6735 |
{ |
| 2748 |
delete tempStringStruct;//label |
6736 |
// not an error |
|
|
6737 |
return true; |
| 6738 |
} |
| 2749 |
|
6739 |
|
| 2750 |
tempStringStruct = this->GetLine(input); |
6740 |
vtkFoamDict& faceZoneDict = *faceZoneDictPtr; |
| 2751 |
temp = tempStringStruct->value; |
6741 |
size_t nFaceZones = faceZoneDict.size(); |
| 2752 |
delete tempStringStruct;//number of values or flipmap |
|
|
| 2753 |
|
6742 |
|
| 2754 |
if(temp.find("flipMap") == vtkstd::string::npos) |
6743 |
for(size_t i = 0; i < nFaceZones; i++) |
| 2755 |
{ |
6744 |
{ |
| 2756 |
//number of elements |
6745 |
// look up face labels |
| 2757 |
tokenizer << temp; |
6746 |
vtkFoamDict& dict = faceZoneDict.entry(i).dictionary(); |
| 2758 |
tokenizer >> numElement; |
6747 |
vtkFoamEntry& faceLabelsEntry = dict.lookup("faceLabels"); |
| 2759 |
if(numElement == 0) |
6748 |
if(!faceLabelsEntry.found()) |
| 2760 |
{ |
6749 |
{ |
| 2761 |
input->close(); |
6750 |
delete faceZoneDictPtr; |
| 2762 |
delete input; |
6751 |
vtkErrorMacro(<<"faceLabels not found in faceZones"); |
| 2763 |
return NULL; |
6752 |
return false; |
| 2764 |
} |
6753 |
} |
| 2765 |
|
6754 |
|
| 2766 |
//binary |
6755 |
// allocate an empty mesh if the list is empty |
| 2767 |
if(binaryWriteFormat) |
6756 |
if(faceLabelsEntry.firstValue().type() == vtkFoamToken::EMPTYLIST) |
| 2768 |
{ |
6757 |
{ |
| 2769 |
input->get(); //parenthesis |
6758 |
vtkUnstructuredGrid *fzm = vtkUnstructuredGrid::New(); |
| 2770 |
for(int j = 0; j < numElement; j++) |
6759 |
faceZoneMesh->push_back(fzm); |
| 2771 |
{ |
6760 |
// set name |
| 2772 |
input->read((char *) &tempElement, sizeof(int)); |
6761 |
this->SetDataObjectName(fzm, faceZoneDict.entry(i).keyword()); |
| 2773 |
faceZone.push_back(tempElement); |
6762 |
continue; |
| 2774 |
} |
|
|
| 2775 |
} |
6763 |
} |
| 2776 |
|
6764 |
|
| 2777 |
//ascii |
6765 |
if(faceLabelsEntry.firstValue().type() != vtkFoamToken::LABELLIST) |
| 2778 |
else |
|
|
| 2779 |
{ |
6766 |
{ |
| 2780 |
//THROW OUT ( |
6767 |
delete faceZoneDictPtr; |
| 2781 |
tempStringStruct = this->GetLine(input); |
6768 |
vtkErrorMacro(<<"faceLabels not of type labelList"); |
| 2782 |
temp = tempStringStruct->value; |
6769 |
return false; |
| 2783 |
delete tempStringStruct; |
6770 |
} |
| 2784 |
|
6771 |
|
| 2785 |
//get each element & add to vector |
6772 |
vtkIntArray &labels = faceLabelsEntry.labelList(); |
| 2786 |
for(int j = 0; j < numElement; j++) |
|
|
| 2787 |
{ |
| 2788 |
tempStringStruct = this->GetLine(input); |
| 2789 |
temp = tempStringStruct->value; |
| 2790 |
delete tempStringStruct; |
| 2791 |
|
6773 |
|
| 2792 |
tokenizer.clear(); |
6774 |
int nFaces = labels.GetNumberOfTuples(); |
| 2793 |
tokenizer << temp; |
6775 |
if(nFaces > this->FaceOwner->GetNumberOfTuples()) |
| 2794 |
tokenizer >> tempElement; |
6776 |
{ |
| 2795 |
faceZone.push_back(tempElement); |
6777 |
vtkErrorMacro(<<"The length of faceLabels " << nFaces |
| 2796 |
} |
6778 |
<< " for faceZone " << faceZoneDict.entry(i).keyword().c_str() |
|
|
6779 |
<< " exceeds the number of faces " |
| 6780 |
<< this->FaceOwner->GetNumberOfTuples()); |
| 6781 |
delete faceZoneDictPtr; |
| 6782 |
return false; |
| 2797 |
} |
6783 |
} |
| 2798 |
} |
|
|
| 2799 |
|
6784 |
|
| 2800 |
//Create the mesh |
6785 |
// allocate new grid: we do not use resize() beforehand since it |
| 2801 |
int k; |
6786 |
// could lead to undefined pointer if we return by error |
| 2802 |
vtkTriangle * triangle; |
6787 |
faceZoneMesh->push_back(vtkUnstructuredGrid::New()); |
| 2803 |
vtkQuad * quad; |
6788 |
vtkUnstructuredGrid *fzm = faceZoneMesh->back(); |
| 2804 |
vtkPolygon * polygon; |
|
|
| 2805 |
|
6789 |
|
| 2806 |
//LOOP THROUGH EACH FACE |
6790 |
// set faceZone size |
| 2807 |
for(int j = 0; j < (int)faceZone.size(); j++) |
6791 |
fzm->Allocate(nFaces); |
| 2808 |
{ |
|
|
| 2809 |
|
6792 |
|
| 2810 |
//Triangular Face |
6793 |
// aloocate array for converting int vector to vtkIdType vector: |
| 2811 |
if(this->FacePoints->value[faceZone[j]].size() == 3) |
6794 |
// workaround for 64bit machines |
|
|
6795 |
int maxNFacePoints = 0; |
| 6796 |
for(int j = 0; j < nFaces; j++) |
| 2812 |
{ |
6797 |
{ |
| 2813 |
triangle = vtkTriangle::New(); |
6798 |
const int nFacePoints = facesPoints->size(labels.GetValue(j)); |
| 2814 |
for(k = 0; k < 3; k++) |
6799 |
if(nFacePoints > maxNFacePoints) |
| 2815 |
{ |
6800 |
{ |
| 2816 |
triangle->GetPointIds()->SetId(k, this->FacePoints->value[ |
6801 |
maxNFacePoints = nFacePoints; |
| 2817 |
faceZone[j]][k]); |
|
|
| 2818 |
} |
6802 |
} |
| 2819 |
faceZoneMesh->InsertNextCell(triangle->GetCellType(), |
|
|
| 2820 |
triangle->GetPointIds()); |
| 2821 |
triangle->Delete(); |
| 2822 |
} |
6803 |
} |
|
|
6804 |
vtkIdList* facePointsVtkId = vtkIdList::New(); |
| 6805 |
facePointsVtkId->SetNumberOfIds(maxNFacePoints); |
| 2823 |
|
6806 |
|
| 2824 |
//Quadraic Face |
6807 |
// insert faces |
| 2825 |
else if(this->FacePoints->value[faceZone[j]].size() == 4) |
6808 |
this->InsertFacesToGrid(fzm, facesPoints, 0, nFaces, NULL, facePointsVtkId, |
| 2826 |
{ |
6809 |
&labels, false); |
| 2827 |
quad = vtkQuad::New(); |
|
|
| 2828 |
for(k = 0; k < 4; k++) |
| 2829 |
{ |
| 2830 |
quad->GetPointIds()->SetId(k, |
| 2831 |
this->FacePoints->value[faceZone[j]][k]); |
| 2832 |
} |
| 2833 |
faceZoneMesh->InsertNextCell(quad->GetCellType(), |
| 2834 |
quad->GetPointIds()); |
| 2835 |
quad->Delete(); |
| 2836 |
} |
| 2837 |
|
6810 |
|
| 2838 |
//Polygonal Face |
6811 |
facePointsVtkId->Delete(); |
| 2839 |
else |
6812 |
fzm->SetPoints(points); |
| 2840 |
{ |
6813 |
|
| 2841 |
polygon = vtkPolygon::New(); |
6814 |
// set name |
| 2842 |
for(k = 0; k < (int)this->FacePoints->value[faceZone[j]].size(); k++) |
6815 |
this->SetDataObjectName(fzm, faceZoneDict.entry(i).keyword()); |
| 2843 |
{ |
|
|
| 2844 |
polygon->GetPointIds()->InsertId(k, this->FacePoints->value[ |
| 2845 |
faceZone[j]][k]); |
| 2846 |
} |
| 2847 |
faceZoneMesh->InsertNextCell(polygon->GetCellType(), |
| 2848 |
polygon->GetPointIds()); |
| 2849 |
polygon->Delete(); |
| 2850 |
} |
| 2851 |
} |
6816 |
} |
| 2852 |
|
6817 |
|
| 2853 |
//set the face zone points |
6818 |
delete faceZoneDictPtr; |
| 2854 |
faceZoneMesh->SetPoints(this->Points); |
6819 |
|
| 2855 |
input->close(); |
|
|
| 2856 |
delete input; |
| 2857 |
vtkDebugMacro(<<"Face zone mesh created"); |
6820 |
vtkDebugMacro(<<"Face zone mesh created"); |
| 2858 |
return faceZoneMesh; |
6821 |
return true; |
| 2859 |
} |
6822 |
} |
| 2860 |
|
6823 |
|
| 2861 |
// **************************************************************************** |
6824 |
//----------------------------------------------------------------------------- |
| 2862 |
// Method: vtkOpenFOAMReader::GetCellZoneMesh |
6825 |
// returns a requested cell zone mesh |
| 2863 |
// |
6826 |
bool vtkOpenFOAMReader::GetCellZoneMesh(unstructuredGridVector* cellZoneMesh, |
| 2864 |
// Purpose: |
6827 |
vtkIntArray *cellFacesList, vtkIntArray *cellFacesIndices, |
| 2865 |
// returns a requested cell zone mesh |
6828 |
const intVectorVector *facesPoints, vtkPoints *points, int timeState) |
| 2866 |
// |
|
|
| 2867 |
// **************************************************************************** |
| 2868 |
vtkUnstructuredGrid * vtkOpenFOAMReader::GetCellZoneMesh(int timeState, |
| 2869 |
int cellZoneIndex) |
| 2870 |
{ |
6829 |
{ |
| 2871 |
vtkUnstructuredGrid * cellZoneMesh = vtkUnstructuredGrid::New(); |
6830 |
vtkDebugMacro(<<"Create cell zone mesh"); |
| 2872 |
vtkstd::string cellZonesPath = this->PathPrefix->value + |
6831 |
|
| 2873 |
this->PolyMeshFacesDir->value[timeState] + |
6832 |
vtkFoamDict* cellZoneDictPtr |
| 2874 |
"/polyMesh/cellZones"; |
6833 |
= this->GatherBlocks("polyMesh/cellZones", timeState, false); |
| 2875 |
vtkDebugMacro(<<"Create cell zone mesh: "<<cellZonesPath.c_str()); |
6834 |
|
| 2876 |
vtkstd::string temp; |
6835 |
if(cellZoneDictPtr == NULL) |
| 2877 |
stdString* tempStringStruct; |
|
|
| 2878 |
bool binaryWriteFormat; |
| 2879 |
ifstream * input = new ifstream(cellZonesPath.c_str(), ios::in VTK_IOS_NOCREATE); |
| 2880 |
//make sure file exists |
| 2881 |
if(input->fail()) |
| 2882 |
{ |
6836 |
{ |
| 2883 |
input->close(); |
6837 |
// not an error |
| 2884 |
delete input; |
6838 |
return true; |
| 2885 |
return cellZoneMesh; |
|
|
| 2886 |
} |
6839 |
} |
| 2887 |
|
6840 |
|
| 2888 |
//determine if file is binary or ascii |
6841 |
vtkFoamDict& cellZoneDict = *cellZoneDictPtr; |
| 2889 |
while(temp.find("format") == vtkstd::string::npos) |
6842 |
size_t nCellZones = cellZoneDict.size(); |
|
|
6843 |
|
| 6844 |
for(size_t i = 0; i < nCellZones; i++) |
| 2890 |
{ |
6845 |
{ |
| 2891 |
tempStringStruct = this->GetLine(input); |
6846 |
// look up cell labels |
| 2892 |
temp = tempStringStruct->value; |
6847 |
vtkFoamDict& dict = cellZoneDict.entry(i).dictionary(); |
| 2893 |
delete tempStringStruct; |
6848 |
vtkFoamEntry& cellLabelsEntry = dict.lookup("cellLabels"); |
|
|
6849 |
if(!cellLabelsEntry.found()) |
| 6850 |
{ |
| 6851 |
delete cellZoneDictPtr; |
| 6852 |
vtkErrorMacro(<<"cellLabels not found in cellZones"); |
| 6853 |
return false; |
| 6854 |
} |
| 6855 |
|
| 6856 |
// allocate an empty mesh if the list is empty |
| 6857 |
if(cellLabelsEntry.firstValue().type() == vtkFoamToken::EMPTYLIST) |
| 6858 |
{ |
| 6859 |
vtkUnstructuredGrid *czm = vtkUnstructuredGrid::New(); |
| 6860 |
cellZoneMesh->push_back(czm); |
| 6861 |
// set name |
| 6862 |
this->SetDataObjectName(czm, cellZoneDict.entry(i).keyword()); |
| 6863 |
continue; |
| 6864 |
} |
| 6865 |
|
| 6866 |
if(cellLabelsEntry.firstValue().type() != vtkFoamToken::LABELLIST) |
| 6867 |
{ |
| 6868 |
delete cellZoneDictPtr; |
| 6869 |
vtkErrorMacro(<<"cellLabels not of type labelList"); |
| 6870 |
return false; |
| 6871 |
} |
| 6872 |
|
| 6873 |
vtkIntArray &labels = cellLabelsEntry.labelList(); |
| 6874 |
|
| 6875 |
int nCells = labels.GetNumberOfTuples(); |
| 6876 |
if(nCells > this->NumCells) |
| 6877 |
{ |
| 6878 |
vtkErrorMacro(<<"The length of cellLabels " << nCells |
| 6879 |
<< " for cellZone " << cellZoneDict.entry(i).keyword().c_str() |
| 6880 |
<< " exceeds the number of cells " << this->NumCells); |
| 6881 |
delete cellZoneDictPtr; |
| 6882 |
return false; |
| 6883 |
} |
| 6884 |
|
| 6885 |
// allocate new grid: we do not use resize() beforehand since it |
| 6886 |
// could lead to undefined pointers if we return by error |
| 6887 |
cellZoneMesh->push_back(vtkUnstructuredGrid::New()); |
| 6888 |
vtkUnstructuredGrid* czm = cellZoneMesh->back(); |
| 6889 |
|
| 6890 |
// set cellZone size |
| 6891 |
czm->Allocate(nCells); |
| 6892 |
|
| 6893 |
// insert cells |
| 6894 |
this->InsertCellsToGrid(czm, cellFacesList, cellFacesIndices, facesPoints, |
| 6895 |
NULL, NULL, &labels); |
| 6896 |
|
| 6897 |
// set cell zone points |
| 6898 |
czm->SetPoints(points); |
| 6899 |
|
| 6900 |
// set name |
| 6901 |
this->SetDataObjectName(czm, cellZoneDict.entry(i).keyword()); |
| 2894 |
} |
6902 |
} |
| 2895 |
input->close(); |
|
|
| 2896 |
|
6903 |
|
| 2897 |
//reopen file in correct format |
6904 |
delete cellZoneDictPtr; |
| 2898 |
if(temp.find("binary") != vtkstd::string::npos) |
6905 |
vtkDebugMacro(<<"Cell zone mesh created"); |
|
|
6906 |
return true; |
| 6907 |
} |
| 6908 |
|
| 6909 |
//----------------------------------------------------------------------------- |
| 6910 |
void vtkOpenFOAMReader::AddArrayToFieldData(vtkDataSetAttributes *fieldData, |
| 6911 |
vtkDataArray *array, const vtkStdString &arrayName) |
| 6912 |
{ |
| 6913 |
// exclude dimensional unit string if any |
| 6914 |
const vtkStdString arrayNameString(arrayName.substr(0, arrayName.find(' '))); |
| 6915 |
array->SetName(arrayName.c_str()); |
| 6916 |
|
| 6917 |
if(array->GetNumberOfComponents() == 1 |
| 6918 |
#if 0 |
| 6919 |
&& (fieldData->IsA("vtkPointData") && arrayNameString == "CellToPoint[p]" |
| 6920 |
|| fieldData->IsA("vtkCellData") && arrayNameString == "p") |
| 6921 |
#else |
| 6922 |
&& arrayNameString == "p" |
| 6923 |
#endif |
| 6924 |
) |
| 2899 |
{ |
6925 |
{ |
| 2900 |
#ifdef _WIN32 |
6926 |
fieldData->SetScalars(array); |
| 2901 |
input->open(cellZonesPath.c_str(), ios::binary | ios::in VTK_IOS_NOCREATE); |
6927 |
} |
|
|
6928 |
else if(array->GetNumberOfComponents() == 3 |
| 6929 |
#if 0 |
| 6930 |
&& (fieldData->IsA("vtkPointData") && arrayNameString == "CellToPoint[U]" |
| 6931 |
|| fieldData->IsA("vtkCellData") && arrayNameString == "U") |
| 2902 |
#else |
6932 |
#else |
| 2903 |
input->open(cellZonesPath.c_str(), ios::in VTK_IOS_NOCREATE); |
6933 |
&& arrayNameString == "U" |
| 2904 |
#endif |
6934 |
#endif |
| 2905 |
binaryWriteFormat = true; |
6935 |
) |
|
|
6936 |
{ |
| 6937 |
fieldData->SetVectors(array); |
| 2906 |
} |
6938 |
} |
| 2907 |
else |
6939 |
else |
| 2908 |
{ |
6940 |
{ |
| 2909 |
input->open(cellZonesPath.c_str(),ios::in); |
6941 |
fieldData->AddArray(array); |
| 2910 |
binaryWriteFormat = false; |
|
|
| 2911 |
} |
6942 |
} |
|
|
6943 |
} |
| 2912 |
|
6944 |
|
| 2913 |
vtkstd::string token; |
6945 |
//----------------------------------------------------------------------------- |
| 2914 |
vtksys_ios::stringstream tokenizer; |
6946 |
// return 0 if there's any error, 1 if success |
| 2915 |
vtkstd::vector< int > cellZone; |
6947 |
int vtkOpenFOAMReader::CreateDataSet(vtkMultiBlockDataSet *output, |
| 2916 |
int tempElement; |
6948 |
int timeState) |
| 2917 |
vtkstd::vector< vtkstd::vector < int > > tempElementZones; |
6949 |
{ |
| 2918 |
int numElement; |
6950 |
const bool recreateInternalMesh = (!this->CacheMesh) |
|
|
6951 |
|| this->TimeStepOld == -1 |
| 6952 |
|| this->PolyMeshFacesDir->GetValue(timeState) |
| 6953 |
!= this->PolyMeshFacesDir->GetValue(this->TimeStepOld) |
| 6954 |
|| this->FaceOwner == NULL |
| 6955 |
|| (this->PatchSelectionStatus & 0x02) |
| 6956 |
!= (this->PatchSelectionOldStatus & 0x02) |
| 6957 |
|| this->DecomposePolyhedra != this->DecomposePolyhedraOld |
| 6958 |
|| this->ReadZones != this->ReadZonesOld |
| 6959 |
|| this->KeepPatches != this->KeepPatchesOld |
| 6960 |
|| this->ListTimeStepsByControlDict != this->ListTimeStepsByControlDictOld; |
| 2919 |
|
6961 |
|
| 2920 |
//find desired mesh entry |
6962 |
const bool recreateBoundaryMesh = recreateInternalMesh |
| 2921 |
while(temp.find(this->CellZoneNames->value[cellZoneIndex]) == |
6963 |
|| this->PatchSelectionStatus != this->PatchSelectionOldStatus |
| 2922 |
vtkstd::string::npos) |
6964 |
|| this->CreateCellToPoint != this->CreateCellToPointOld; |
| 2923 |
{ |
|
|
| 2924 |
tempStringStruct = this->GetLine(input); |
| 2925 |
temp = tempStringStruct->value; |
| 2926 |
delete tempStringStruct; |
| 2927 |
} |
| 2928 |
tempStringStruct = this->GetLine(input); |
| 2929 |
temp = tempStringStruct->value; |
| 2930 |
delete tempStringStruct;//throw out { |
| 2931 |
|
6965 |
|
| 2932 |
tempStringStruct = this->GetLine(input); |
6966 |
const bool updateVariables = recreateBoundaryMesh |
| 2933 |
temp = tempStringStruct->value; |
6967 |
|| timeState != this->TimeStepOld |
| 2934 |
delete tempStringStruct;//type |
6968 |
|| this->CellSelectionStatus != this->CellSelectionOldStatus |
|
|
6969 |
|| this->PointSelectionStatus != this->PointSelectionOldStatus |
| 6970 |
|| this->LagrangianSelectionStatus != this->LagrangianSelectionOldStatus |
| 6971 |
|| this->PositionsIsIn13Format != this->PositionsIsIn13FormatOld |
| 6972 |
|| this->AddDimensionsToArrayNames != this->AddDimensionsToArrayNamesOld; |
| 2935 |
|
6973 |
|
| 2936 |
tempStringStruct = this->GetLine(input); |
6974 |
const bool pointsMoved = this->TimeStepOld == -1 |
| 2937 |
temp = tempStringStruct->value; |
6975 |
|| this->PolyMeshPointsDir->GetValue(timeState) |
| 2938 |
delete tempStringStruct; |
6976 |
!= this->PolyMeshPointsDir->GetValue(this->TimeStepOld); |
| 2939 |
|
6977 |
|
| 2940 |
tempStringStruct = this->GetLine(input); |
6978 |
const bool moveInternalPoints = !recreateInternalMesh && pointsMoved; |
| 2941 |
temp = tempStringStruct->value; |
6979 |
const bool moveBoundaryPoints = !recreateBoundaryMesh && pointsMoved; |
| 2942 |
delete tempStringStruct; |
|
|
| 2943 |
|
6980 |
|
| 2944 |
//number of elements |
6981 |
// determine if we need to reconstruct meshes |
| 2945 |
tokenizer << temp; |
6982 |
if(recreateInternalMesh) |
| 2946 |
tokenizer >> numElement; |
6983 |
{ |
|
|
6984 |
this->ClearInternalMeshes(); |
| 6985 |
} |
| 6986 |
if(recreateBoundaryMesh) |
| 6987 |
{ |
| 6988 |
this->ClearBoundaryMeshes(); |
| 6989 |
} |
| 2947 |
|
6990 |
|
| 2948 |
//binary |
6991 |
intVectorVector *facePoints = NULL; |
| 2949 |
if(binaryWriteFormat) |
6992 |
vtkStdString meshDir; |
|
|
6993 |
if(recreateInternalMesh || recreateBoundaryMesh) |
| 2950 |
{ |
6994 |
{ |
| 2951 |
input->get(); //parenthesis |
6995 |
meshDir = *this->PathPrefix |
| 2952 |
for(int j = 0; j < numElement; j++) |
6996 |
+ this->PolyMeshFacesDir->GetValue(timeState) + "/polyMesh/"; |
|
|
6997 |
|
| 6998 |
// create paths to polyMesh files |
| 6999 |
vtkStdString facesPath = meshDir + "faces"; |
| 7000 |
// create the faces vector |
| 7001 |
facePoints = this->ReadFacesFile(facesPath.c_str()); |
| 7002 |
if(facePoints == NULL) |
| 2953 |
{ |
7003 |
{ |
| 2954 |
input->read((char *) &tempElement, sizeof(int)); |
7004 |
return 0; |
| 2955 |
cellZone.push_back(tempElement); |
|
|
| 2956 |
} |
7005 |
} |
|
|
7006 |
this->UpdateProgress(0.2); |
| 2957 |
} |
7007 |
} |
| 2958 |
|
7008 |
|
| 2959 |
//ascii |
7009 |
vtkIntArray *cellFacesList = NULL; |
| 2960 |
else |
7010 |
vtkIntArray *cellFacesIndices = NULL; |
|
|
7011 |
if(recreateInternalMesh) |
| 2961 |
{ |
7012 |
{ |
| 2962 |
tempStringStruct = this->GetLine(input); |
7013 |
vtkStdString ownerPath = meshDir + "owner"; |
| 2963 |
temp = tempStringStruct->value; |
7014 |
vtkStdString neighborPath = meshDir + "neighbour"; |
| 2964 |
delete tempStringStruct;//throw out ( |
|
|
| 2965 |
|
7015 |
|
| 2966 |
//get each element & add to vector |
7016 |
// read owner/neighbor and create the faces owner/facesOfCell vector |
| 2967 |
for(int j = 0; j < numElement; j++) |
7017 |
cellFacesList = vtkIntArray::New(); |
| 2968 |
{ |
7018 |
cellFacesIndices = vtkIntArray::New(); |
| 2969 |
tempStringStruct = this->GetLine(input); |
|
|
| 2970 |
temp = tempStringStruct->value; |
| 2971 |
delete tempStringStruct; |
| 2972 |
|
7019 |
|
| 2973 |
tokenizer.clear(); |
7020 |
if(!this->ReadOwnerNeighborFiles(cellFacesList, cellFacesIndices, |
| 2974 |
tokenizer << temp; |
7021 |
ownerPath.c_str(), neighborPath.c_str())) |
| 2975 |
tokenizer >> tempElement; |
7022 |
{ |
| 2976 |
cellZone.push_back(tempElement); |
7023 |
delete facePoints; |
|
|
7024 |
cellFacesList->Delete(); |
| 7025 |
cellFacesIndices->Delete(); |
| 7026 |
return 0; |
| 2977 |
} |
7027 |
} |
|
|
7028 |
if(static_cast<vtkIdType>(facePoints->nElements()) |
| 7029 |
!= this->FaceOwner->GetNumberOfTuples()) |
| 7030 |
{ |
| 7031 |
vtkErrorMacro(<< "The numbers of faces in faces and owners don't match: " |
| 7032 |
<< "faces = " << facePoints->nElements() << ", owners = " |
| 7033 |
<< this->FaceOwner->GetNumberOfTuples()); |
| 7034 |
delete facePoints; |
| 7035 |
cellFacesList->Delete(); |
| 7036 |
cellFacesIndices->Delete(); |
| 7037 |
return 0; |
| 7038 |
} |
| 7039 |
this->UpdateProgress(0.3); |
| 2978 |
} |
7040 |
} |
| 2979 |
|
7041 |
|
| 2980 |
//Create the mesh |
7042 |
vtkFloatArray *pointArray = NULL; |
| 2981 |
bool foundDup = false; |
7043 |
if(recreateInternalMesh || (recreateBoundaryMesh && !recreateInternalMesh |
| 2982 |
vtkstd::vector< int > cellPoints; |
7044 |
&& this->InternalMesh == NULL) || moveInternalPoints || moveBoundaryPoints) |
| 2983 |
vtkstd::vector< int > tempFaces[2]; |
|
|
| 2984 |
vtkstd::vector< int > firstFace; |
| 2985 |
int pivotPoint = 0; |
| 2986 |
int i, j, k, l, pCount; |
| 2987 |
int faceCount = 0; |
| 2988 |
|
| 2989 |
//Create Mesh |
| 2990 |
for(i = 0; i < (int)cellZone.size(); i++) //each cell |
| 2991 |
{ |
7045 |
{ |
| 2992 |
//calculate total points for all faces of a cell |
7046 |
// get the points |
| 2993 |
//used to determine cell type |
7047 |
pointArray = this->ReadPointsFile(timeState); |
| 2994 |
int totalPointCount = 0; |
7048 |
if(pointArray == NULL && recreateInternalMesh) |
| 2995 |
for(j = 0; j < (int)this->FacesOfCell->value[ |
|
|
| 2996 |
cellZone[i]].size(); j++) //each face |
| 2997 |
{ |
7049 |
{ |
| 2998 |
totalPointCount += (int)this->FacePoints->value[this->FacesOfCell->value[ |
7050 |
delete facePoints; |
| 2999 |
cellZone[i]][j].faceIndex].size(); |
7051 |
cellFacesList->Delete(); |
|
|
7052 |
cellFacesIndices->Delete(); |
| 7053 |
return 0; |
| 3000 |
} |
7054 |
} |
|
|
7055 |
this->UpdateProgress(0.4); |
| 7056 |
} |
| 3001 |
|
7057 |
|
| 3002 |
// using cell type - order points, create cell, add to mesh |
7058 |
// make internal mesh |
| 3003 |
|
7059 |
// Create Internal Mesh only if required for display |
| 3004 |
//OFhex | vtkHexahedron |
7060 |
if(recreateInternalMesh) |
| 3005 |
if (totalPointCount == 24) |
7061 |
{ |
|
|
7062 |
if(this->GetPatchArrayStatus(GetPatchArrayName(0))) |
| 3006 |
{ |
7063 |
{ |
| 3007 |
faceCount = 0; |
7064 |
this->InternalMesh = this->MakeInternalMesh(cellFacesList, |
| 3008 |
|
7065 |
cellFacesIndices, facePoints, pointArray); |
| 3009 |
//get first face |
7066 |
} |
| 3010 |
for(j = 0; j < (int)this->FacePoints->value[this->FacesOfCell->value[ |
7067 |
// read and construct zones |
| 3011 |
cellZone[i]][0].faceIndex].size(); j++) |
7068 |
if(this->ReadZones) |
| 3012 |
{ |
7069 |
{ |
| 3013 |
firstFace.push_back(this->FacePoints->value[this->FacesOfCell->value[ |
7070 |
vtkPoints *points; |
| 3014 |
cellZone[i]][0].faceIndex][j]); |
7071 |
if(this->InternalMesh != NULL) |
| 3015 |
} |
|
|
| 3016 |
|
| 3017 |
//-if it is a neighbor face flip it |
| 3018 |
if(FacesOfCell->value[i][0].neighborFace) |
| 3019 |
{ |
7072 |
{ |
| 3020 |
int tempPop; |
7073 |
points = this->InternalMesh->GetPoints(); |
| 3021 |
for(k = 0; k < (int)firstFace.size() - 1; k++) |
|
|
| 3022 |
{ |
| 3023 |
tempPop = firstFace[firstFace.size()-1]; |
| 3024 |
firstFace.pop_back(); |
| 3025 |
firstFace.insert(firstFace.begin()+1+k, tempPop); |
| 3026 |
} |
| 3027 |
} |
7074 |
} |
| 3028 |
|
7075 |
else |
| 3029 |
//add first face to cell points |
|
|
| 3030 |
for(j =0; j < (int)firstFace.size(); j++) |
| 3031 |
{ |
7076 |
{ |
| 3032 |
cellPoints.push_back(firstFace[j]); |
7077 |
points = vtkPoints::New(); |
|
|
7078 |
points->SetData(pointArray); |
| 3033 |
} |
7079 |
} |
| 3034 |
|
7080 |
|
| 3035 |
for(int pointCount = 0;pointCount < (int)firstFace.size();pointCount++) |
7081 |
this->PointZoneMesh = new unstructuredGridVector; |
|
|
7082 |
if(!this->GetPointZoneMesh(this->PointZoneMesh, points, timeState)) |
| 3036 |
{ |
7083 |
{ |
| 3037 |
//find the 2 other faces containing each point - start with face 1 |
7084 |
delete this->PointZoneMesh; |
| 3038 |
for(j = 1; j < (int)this->FacesOfCell->value[ |
7085 |
this->PointZoneMesh = NULL; |
| 3039 |
cellZone[i]].size(); j++) //each face |
7086 |
delete facePoints; |
|
|
7087 |
cellFacesList->Delete(); |
| 7088 |
cellFacesIndices->Delete(); |
| 7089 |
if(this->InternalMesh == NULL) |
| 3040 |
{ |
7090 |
{ |
| 3041 |
for(k = 0; k < (int)this->FacePoints->value[this->FacesOfCell-> |
7091 |
points->Delete(); |
| 3042 |
value[cellZone[i]][j].faceIndex].size(); k++) |
|
|
| 3043 |
{ |
| 3044 |
if(firstFace[pointCount] == this->FacePoints-> |
| 3045 |
value[this->FacesOfCell->value[cellZone[i]][j].faceIndex][k]) |
| 3046 |
{ |
| 3047 |
//another face with the point |
| 3048 |
for(l = 0; l < (int)this->FacePoints->value[this->FacesOfCell-> |
| 3049 |
value[cellZone[i]][j].faceIndex].size(); l++) |
| 3050 |
{ |
| 3051 |
tempFaces[faceCount].push_back(this->FacePoints->value[ |
| 3052 |
this->FacesOfCell->value[cellZone[i]][j].faceIndex] |
| 3053 |
[l]); |
| 3054 |
} |
| 3055 |
faceCount++; |
| 3056 |
} |
| 3057 |
} |
| 3058 |
} |
| 3059 |
|
| 3060 |
//locate the pivot point contained in faces 0 & 1 |
| 3061 |
for(j = 0; j < (int)tempFaces[0].size(); j++) |
| 3062 |
{ |
| 3063 |
for(k = 0; k < (int)tempFaces[1].size(); k++) |
| 3064 |
{ |
| 3065 |
if(tempFaces[0][j] == tempFaces[1][k] && tempFaces[0][j] != |
| 3066 |
firstFace[pointCount]) |
| 3067 |
{ |
| 3068 |
pivotPoint = tempFaces[0][j]; |
| 3069 |
break; |
| 3070 |
} |
| 3071 |
} |
| 3072 |
} |
7092 |
} |
| 3073 |
cellPoints.push_back(pivotPoint); |
7093 |
pointArray->Delete(); |
| 3074 |
tempFaces[0].clear(); |
7094 |
return 0; |
| 3075 |
tempFaces[1].clear(); |
|
|
| 3076 |
faceCount=0; |
| 3077 |
} |
7095 |
} |
| 3078 |
|
7096 |
if(this->PointZoneMesh->size() == 0) |
| 3079 |
//create the hex cell and insert it into the mesh |
7097 |
{ |
| 3080 |
vtkHexahedron * hexahedron = vtkHexahedron::New(); |
7098 |
delete this->PointZoneMesh; |
| 3081 |
for(pCount = 0; pCount < (int)cellPoints.size(); pCount++) |
7099 |
this->PointZoneMesh = NULL; |
| 3082 |
{ |
|
|
| 3083 |
hexahedron->GetPointIds()->SetId(pCount, cellPoints[pCount]); |
| 3084 |
} |
| 3085 |
cellZoneMesh->InsertNextCell(hexahedron->GetCellType(), |
| 3086 |
hexahedron->GetPointIds()); |
| 3087 |
hexahedron->Delete(); |
| 3088 |
cellPoints.clear(); |
| 3089 |
firstFace.clear(); |
| 3090 |
} |
7100 |
} |
| 3091 |
|
7101 |
|
| 3092 |
//OFprism | vtkWedge |
7102 |
this->FaceZoneMesh = new unstructuredGridVector; |
| 3093 |
else if (totalPointCount == 18) |
7103 |
if(!this->GetFaceZoneMesh(this->FaceZoneMesh, facePoints, points, |
| 3094 |
{ |
7104 |
timeState)) |
| 3095 |
faceCount = 0; |
|
|
| 3096 |
int index = 0; |
| 3097 |
|
| 3098 |
//find first triangular face |
| 3099 |
for(j = 0; j < (int)this->FacesOfCell->value[ |
| 3100 |
cellZone[i]].size(); j++) //each face |
| 3101 |
{ |
7105 |
{ |
| 3102 |
if((int)this->FacePoints->value[this->FacesOfCell->value[ |
7106 |
delete this->FaceZoneMesh; |
| 3103 |
cellZone[i]][j].faceIndex].size() == 3) |
7107 |
this->FaceZoneMesh = NULL; |
|
|
7108 |
delete this->PointZoneMesh; |
| 7109 |
this->PointZoneMesh = NULL; |
| 7110 |
delete facePoints; |
| 7111 |
cellFacesList->Delete(); |
| 7112 |
cellFacesIndices->Delete(); |
| 7113 |
if(this->InternalMesh == NULL) |
| 3104 |
{ |
7114 |
{ |
| 3105 |
for(k = 0; k < (int)this->FacePoints->value[this->FacesOfCell->value[ |
7115 |
points->Delete(); |
| 3106 |
cellZone[i]][j].faceIndex].size(); k++) |
|
|
| 3107 |
{ |
| 3108 |
firstFace.push_back(this->FacePoints->value[this->FacesOfCell-> |
| 3109 |
value[cellZone[i]][j].faceIndex][k]); |
| 3110 |
index = j; |
| 3111 |
} |
| 3112 |
break; |
| 3113 |
} |
7116 |
} |
|
|
7117 |
pointArray->Delete(); |
| 7118 |
return 0; |
| 3114 |
} |
7119 |
} |
| 3115 |
|
7120 |
if(this->FaceZoneMesh->size() == 0) |
| 3116 |
//-if it is a neighbor face flip it |
|
|
| 3117 |
if(this->FacesOfCell->value[i][0].neighborFace) |
| 3118 |
{ |
7121 |
{ |
| 3119 |
int tempPop; |
7122 |
delete this->FaceZoneMesh; |
| 3120 |
for(k = 0; k < (int)firstFace.size() - 1; k++) |
7123 |
this->FaceZoneMesh = NULL; |
|
|
7124 |
} |
| 7125 |
|
| 7126 |
this->CellZoneMesh = new unstructuredGridVector; |
| 7127 |
if(!this->GetCellZoneMesh(this->CellZoneMesh, cellFacesList, |
| 7128 |
cellFacesIndices, facePoints, points, timeState)) |
| 7129 |
{ |
| 7130 |
delete this->CellZoneMesh; |
| 7131 |
this->CellZoneMesh = NULL; |
| 7132 |
delete this->FaceZoneMesh; |
| 7133 |
this->FaceZoneMesh = NULL; |
| 7134 |
delete this->PointZoneMesh; |
| 7135 |
this->PointZoneMesh = NULL; |
| 7136 |
delete facePoints; |
| 7137 |
cellFacesList->Delete(); |
| 7138 |
cellFacesIndices->Delete(); |
| 7139 |
if(this->InternalMesh == NULL) |
| 3121 |
{ |
7140 |
{ |
| 3122 |
tempPop = firstFace[firstFace.size()-1]; |
7141 |
points->Delete(); |
| 3123 |
firstFace.pop_back(); |
|
|
| 3124 |
firstFace.insert(firstFace.begin()+1+k, tempPop); |
| 3125 |
} |
7142 |
} |
|
|
7143 |
pointArray->Delete(); |
| 7144 |
return 0; |
| 3126 |
} |
7145 |
} |
| 3127 |
|
7146 |
if(this->CellZoneMesh->size() == 0) |
| 3128 |
//add first face to cell points |
|
|
| 3129 |
for(j =0; j < (int)firstFace.size(); j++) |
| 3130 |
{ |
7147 |
{ |
| 3131 |
cellPoints.push_back(firstFace[j]); |
7148 |
delete this->CellZoneMesh; |
|
|
7149 |
this->CellZoneMesh = NULL; |
| 3132 |
} |
7150 |
} |
| 3133 |
|
7151 |
if(this->InternalMesh == NULL) |
| 3134 |
for(int pointCount = 0;pointCount < (int)firstFace.size();pointCount++) |
|
|
| 3135 |
{ |
7152 |
{ |
| 3136 |
//find the 2 other faces containing each point |
7153 |
points->Delete(); |
| 3137 |
for(j = 0; j < (int)this->FacesOfCell->value[ |
|
|
| 3138 |
cellZone[i]].size(); j++) //each face |
| 3139 |
{ |
| 3140 |
for(k = 0; k < (int)this->FacePoints->value[this->FacesOfCell->value[ |
| 3141 |
cellZone[i]][j].faceIndex].size(); k++) //each point |
| 3142 |
{ |
| 3143 |
if(firstFace[pointCount] == this->FacePoints-> |
| 3144 |
value[this->FacesOfCell->value[cellZone[i]][j].faceIndex][k] && |
| 3145 |
j != index) |
| 3146 |
{ |
| 3147 |
//another face with point |
| 3148 |
for(l = 0; l < (int)this->FacePoints->value[this-> |
| 3149 |
FacesOfCell->value[cellZone[i]][j].faceIndex].size(); l++) |
| 3150 |
{ |
| 3151 |
tempFaces[faceCount].push_back(this->FacePoints->value[ |
| 3152 |
this->FacesOfCell->value[cellZone[i]][j].faceIndex] |
| 3153 |
[l]); |
| 3154 |
} |
| 3155 |
faceCount++; |
| 3156 |
} |
| 3157 |
} |
| 3158 |
} |
| 3159 |
|
| 3160 |
//locate the pivot point contained in faces 0 & 1 |
| 3161 |
for(j = 0; j < (int)tempFaces[0].size(); j++) |
| 3162 |
{ |
| 3163 |
for(k = 0; k < (int)tempFaces[1].size(); k++) |
| 3164 |
{ |
| 3165 |
if(tempFaces[0][j] == tempFaces[1][k] && tempFaces[0][j] != |
| 3166 |
firstFace[pointCount]) |
| 3167 |
{ |
| 3168 |
pivotPoint = tempFaces[0][j]; |
| 3169 |
break; |
| 3170 |
} |
| 3171 |
} |
| 3172 |
} |
| 3173 |
cellPoints.push_back(pivotPoint); |
| 3174 |
tempFaces[0].clear(); |
| 3175 |
tempFaces[1].clear(); |
| 3176 |
faceCount=0; |
| 3177 |
} |
7154 |
} |
|
|
7155 |
} |
| 7156 |
cellFacesList->Delete(); |
| 7157 |
cellFacesIndices->Delete(); |
| 7158 |
this->TruncateFaceOwner(); |
| 7159 |
} |
| 3178 |
|
7160 |
|
| 3179 |
//create the wedge cell and insert it into the mesh |
7161 |
if(recreateBoundaryMesh) |
| 3180 |
vtkWedge * wedge = vtkWedge::New(); |
7162 |
{ |
| 3181 |
for(pCount = 0; pCount < (int)cellPoints.size(); pCount++) |
7163 |
vtkFloatArray *boundaryPointArray; |
|
|
7164 |
if(pointArray != NULL) |
| 7165 |
{ |
| 7166 |
boundaryPointArray = pointArray; |
| 7167 |
} |
| 7168 |
else |
| 7169 |
{ |
| 7170 |
boundaryPointArray = static_cast<vtkFloatArray *>( |
| 7171 |
this->InternalMesh->GetPoints()->GetData()); |
| 7172 |
} |
| 7173 |
// create boundary mesh |
| 7174 |
this->BoundaryMesh = this->MakeBoundaryMesh(this->BoundaryDict, facePoints, |
| 7175 |
boundaryPointArray); |
| 7176 |
if(this->BoundaryMesh == NULL) |
| 7177 |
{ |
| 7178 |
delete facePoints; |
| 7179 |
if(pointArray != NULL) |
| 3182 |
{ |
7180 |
{ |
| 3183 |
wedge->GetPointIds()->SetId(pCount, cellPoints[pCount]); |
7181 |
pointArray->Delete(); |
| 3184 |
} |
7182 |
} |
| 3185 |
cellZoneMesh->InsertNextCell(wedge->GetCellType(), |
7183 |
return 0; |
| 3186 |
wedge->GetPointIds()); |
|
|
| 3187 |
cellPoints.clear(); |
| 3188 |
wedge->Delete(); |
| 3189 |
firstFace.clear(); |
| 3190 |
} |
7184 |
} |
|
|
7185 |
} |
| 3191 |
|
7186 |
|
| 3192 |
//OFpyramid | vtkPyramid |
7187 |
delete facePoints; |
| 3193 |
else if (totalPointCount == 16) |
7188 |
|
|
|
7189 |
// if only point coordinates change refresh point vector |
| 7190 |
if(moveInternalPoints) |
| 7191 |
{ |
| 7192 |
// refresh the points in each mesh |
| 7193 |
vtkPoints *points; |
| 7194 |
// Check if Internal Mesh exists first.... |
| 7195 |
if(this->InternalMesh != NULL) |
| 7196 |
{ |
| 7197 |
points = this->MoveInternalMesh(this->InternalMesh, pointArray); |
| 7198 |
} |
| 7199 |
else |
| 3194 |
{ |
7200 |
{ |
| 3195 |
foundDup = false; |
7201 |
points = vtkPoints::New(); |
|
|
7202 |
points->SetData(pointArray); |
| 7203 |
} |
| 3196 |
|
7204 |
|
| 3197 |
//find quad |
7205 |
if(this->PointZoneMesh != NULL) |
| 3198 |
for(j = 0; j < (int)this->FacesOfCell->value[ |
7206 |
{ |
| 3199 |
cellZone[i]].size(); j++) //each face |
7207 |
for(size_t i = 0; i < this->PointZoneMesh->size(); i++) |
| 3200 |
{ |
7208 |
{ |
| 3201 |
if((int)this->FacePoints->value[this->FacesOfCell->value[ |
7209 |
this->PointZoneMesh->operator[](i)->SetPoints(points); |
| 3202 |
cellZone[i]][j].faceIndex].size() == 4) |
|
|
| 3203 |
{ |
| 3204 |
for(k = 0; k < (int)this->FacePoints->value[this->FacesOfCell->value[ |
| 3205 |
cellZone[i]][j].faceIndex].size(); k++) |
| 3206 |
{ |
| 3207 |
cellPoints.push_back(this->FacePoints->value[this->FacesOfCell-> |
| 3208 |
value[cellZone[i]][j].faceIndex][k]); |
| 3209 |
} |
| 3210 |
break; |
| 3211 |
} |
| 3212 |
} |
7210 |
} |
| 3213 |
|
7211 |
} |
| 3214 |
//compare first face points to second faces |
7212 |
if(this->FaceZoneMesh != NULL) |
| 3215 |
for(j = 0; j < (int)cellPoints.size(); j++) //each point |
7213 |
{ |
|
|
7214 |
for(size_t i = 0; i < this->FaceZoneMesh->size(); i++) |
| 3216 |
{ |
7215 |
{ |
| 3217 |
for(k = 0; k < (int)this->FacePoints->value[this->FacesOfCell->value[ |
7216 |
this->FaceZoneMesh->operator[](i)->SetPoints(points); |
| 3218 |
cellZone[i]][1].faceIndex].size(); k++) |
|
|
| 3219 |
{ |
| 3220 |
if(cellPoints[j] == this->FacePoints->value[this->FacesOfCell->value[ |
| 3221 |
cellZone[i]][1].faceIndex][k]) |
| 3222 |
{ |
| 3223 |
foundDup = true; |
| 3224 |
} |
| 3225 |
} |
| 3226 |
if(!foundDup) |
| 3227 |
{ |
| 3228 |
cellPoints.push_back(this->FacePoints->value[this->FacesOfCell->value[ |
| 3229 |
cellZone[i]][j].faceIndex][k]); |
| 3230 |
break; |
| 3231 |
} |
| 3232 |
} |
7217 |
} |
| 3233 |
|
7218 |
} |
| 3234 |
//create the pyramid cell and insert it into the mesh |
7219 |
if(this->CellZoneMesh != NULL) |
| 3235 |
vtkPyramid * pyramid = vtkPyramid::New(); |
7220 |
{ |
| 3236 |
for(pCount = 0; pCount < (int)cellPoints.size(); pCount++) |
7221 |
for(size_t i = 0; i < this->CellZoneMesh->size(); i++) |
| 3237 |
{ |
7222 |
{ |
| 3238 |
pyramid->GetPointIds()->SetId(pCount, cellPoints[pCount]); |
7223 |
this->CellZoneMesh->operator[](i)->SetPoints(points); |
| 3239 |
} |
7224 |
} |
| 3240 |
cellZoneMesh->InsertNextCell(pyramid->GetCellType(), |
|
|
| 3241 |
pyramid->GetPointIds()); |
| 3242 |
cellPoints.clear(); |
| 3243 |
pyramid->Delete(); |
| 3244 |
} |
7225 |
} |
|
|
7226 |
points->Delete(); |
| 7227 |
} |
| 3245 |
|
7228 |
|
| 3246 |
//OFtet | vtkTetrahedron |
7229 |
if(moveBoundaryPoints) |
| 3247 |
else if (totalPointCount == 12) |
7230 |
{ |
|
|
7231 |
// Check if Boundary Mesh exists first.... |
| 7232 |
if(this->BoundaryMesh != NULL) |
| 3248 |
{ |
7233 |
{ |
| 3249 |
foundDup = false; |
7234 |
this->MoveBoundaryMesh(this->BoundaryMesh, pointArray); |
|
|
7235 |
} |
| 7236 |
} |
| 7237 |
|
| 7238 |
if(pointArray != NULL) |
| 7239 |
{ |
| 7240 |
pointArray->Delete(); |
| 7241 |
} |
| 7242 |
this->UpdateProgress(0.5); |
| 3250 |
|
7243 |
|
| 3251 |
//grab first face |
7244 |
polyDataVector *lagrangianMesh = new polyDataVector; |
| 3252 |
for(j = 0; j < (int)this->FacePoints->value[this->FacesOfCell->value[ |
7245 |
if(updateVariables) |
| 3253 |
cellZone[i]][0].faceIndex].size(); j++) |
7246 |
{ |
|
|
7247 |
if(!recreateInternalMesh && this->InternalMesh != NULL) |
| 7248 |
{ |
| 7249 |
// clean up arrays of the previous timestep |
| 7250 |
// Check if Internal Mesh Exists first... |
| 7251 |
this->InternalMesh->GetCellData()->Initialize(); |
| 7252 |
this->InternalMesh->GetPointData()->Initialize(); |
| 7253 |
} |
| 7254 |
// Check if Boundary Mesh Exists first... |
| 7255 |
if(!recreateBoundaryMesh && this->BoundaryMesh != NULL) |
| 7256 |
{ |
| 7257 |
for(size_t i = 0; i < this->BoundaryMesh->size(); i++) |
| 3254 |
{ |
7258 |
{ |
| 3255 |
cellPoints.push_back(this->FacePoints->value[this->FacesOfCell->value[ |
7259 |
this->BoundaryMesh->operator[](i)->GetCellData()->Initialize(); |
| 3256 |
cellZone[i]][0].faceIndex][j]); |
7260 |
this->BoundaryMesh->operator[](i)->GetPointData()->Initialize(); |
| 3257 |
} |
7261 |
} |
|
|
7262 |
} |
| 7263 |
// read field data variables into Internal/Boundary meshes |
| 7264 |
for(int i = 0; i < (int)this->VolFieldFiles->GetNumberOfValues(); i++) |
| 7265 |
{ |
| 7266 |
this->GetVolFieldAtTimestep(this->InternalMesh, this->BoundaryMesh, |
| 7267 |
this->BoundaryDict, this->VolFieldFiles->GetValue(i).c_str(), |
| 7268 |
timeState); |
| 7269 |
this->UpdateProgress(0.5 + 0.25 * ((float)(i + 1) |
| 7270 |
/ ((float)this->VolFieldFiles->GetNumberOfValues() + 0.0001))); |
| 7271 |
} |
| 7272 |
for(int i = 0; i < (int)this->PointFieldFiles->GetNumberOfValues(); i++) |
| 7273 |
{ |
| 7274 |
this->GetPointFieldAtTimestep(this->InternalMesh, this->BoundaryMesh, |
| 7275 |
this->BoundaryDict, this->PointFieldFiles->GetValue(i).c_str(), |
| 7276 |
timeState); |
| 7277 |
this->UpdateProgress(0.75 + 0.125 * ((float)(i + 1) |
| 7278 |
/ ((float)this->PointFieldFiles->GetNumberOfValues() + 0.0001))); |
| 7279 |
} |
| 3258 |
|
7280 |
|
| 3259 |
//compare first face points to second faces |
7281 |
// read lagrangian mesh and fields |
| 3260 |
for(j = 0; j < (int)cellPoints.size(); j++) //each point |
7282 |
for(int cloudI = 0; cloudI < this->LagrangianPaths->GetNumberOfTuples(); |
|
|
7283 |
cloudI++) |
| 7284 |
{ |
| 7285 |
const vtkStdString& pathI = this->LagrangianPaths->GetValue(cloudI); |
| 7286 |
if(this->GetPatchArrayStatus(pathI.c_str())) |
| 3261 |
{ |
7287 |
{ |
| 3262 |
for(k = 0; k < (int)this->FacePoints->value[this->FacesOfCell->value[ |
7288 |
// construct lagrangian mesh |
| 3263 |
cellZone[i]][1].faceIndex].size(); k++) |
7289 |
vtkPolyData *meshI = this->MakeLagrangianMesh(timeState, pathI); |
|
|
7290 |
if(meshI == NULL) |
| 7291 |
{ |
| 7292 |
// if mesh doesn't exist we create an empty mesh to keep |
| 7293 |
// node/leaf structure of the multi-block consistent |
| 7294 |
meshI = vtkPolyData::New(); |
| 7295 |
this->SetDataObjectName(meshI, pathI.c_str()); |
| 7296 |
} |
| 7297 |
else |
| 3264 |
{ |
7298 |
{ |
| 3265 |
if(cellPoints[j] == this->FacePoints->value[this->FacesOfCell->value[ |
7299 |
// read lagrangian variables |
| 3266 |
cellZone[i]][1].faceIndex][k]) |
7300 |
for(int i = 0; i < this->LagrangianFieldFiles->GetNumberOfValues(); |
|
|
7301 |
i++) |
| 3267 |
{ |
7302 |
{ |
| 3268 |
foundDup = true; |
7303 |
this->GetLagrangianFieldAtTimestep(meshI, |
|
|
7304 |
this->LagrangianFieldFiles->GetValue(i).c_str(), timeState, |
| 7305 |
pathI); |
| 3269 |
} |
7306 |
} |
| 3270 |
} |
7307 |
} |
| 3271 |
if(!foundDup) |
7308 |
lagrangianMesh->push_back(meshI); |
| 3272 |
{ |
|
|
| 3273 |
cellPoints.push_back(this->FacePoints->value[this->FacesOfCell->value[ |
| 3274 |
cellZone[i]][j].faceIndex][k]); |
| 3275 |
break; |
| 3276 |
} |
| 3277 |
} |
| 3278 |
|
| 3279 |
//create the wedge cell and insert it into the mesh |
| 3280 |
vtkTetra * tetra = vtkTetra::New(); |
| 3281 |
for(pCount = 0; pCount < (int)cellPoints.size(); pCount++) |
| 3282 |
{ |
| 3283 |
tetra->GetPointIds()->SetId(pCount, cellPoints[pCount]); |
| 3284 |
} |
7309 |
} |
| 3285 |
cellZoneMesh->InsertNextCell(tetra->GetCellType(), |
|
|
| 3286 |
tetra->GetPointIds()); |
| 3287 |
cellPoints.clear(); |
| 3288 |
tetra->Delete(); |
| 3289 |
} |
7310 |
} |
|
|
7311 |
} |
| 7312 |
|
| 7313 |
#if PARAVIEW_VERSION_MAJOR >= 3 && PARAVIEW_VERSION_MINOR >= 3 |
| 7314 |
// do nothing |
| 7315 |
#else |
| 7316 |
// assign group to each of data and point/face/cell-Zones |
| 7317 |
int nGroups = 1 |
| 7318 |
+ ((lagrangianMesh->size() != 0 |
| 7319 |
|| this->GetPatchArrayStatus("Lagrangian Particles")) ? 1 : 0) |
| 7320 |
+ (this->PointZoneMesh != NULL ? 1 : 0) |
| 7321 |
+ (this->FaceZoneMesh != NULL ? 1 : 0) |
| 7322 |
+ (this->CellZoneMesh != NULL ? 1 : 0); |
| 7323 |
output->SetNumberOfGroups(nGroups); |
| 7324 |
#endif |
| 7325 |
|
| 7326 |
// set internal mesh/data as output |
| 7327 |
|
| 7328 |
#if PARAVIEW_VERSION_MAJOR >= 3 && PARAVIEW_VERSION_MINOR >= 3 |
| 7329 |
vtkMultiBlockDataSet *eulerians = vtkMultiBlockDataSet::New(); |
| 7330 |
#endif |
| 7331 |
|
| 7332 |
// Add Internal Mesh to final output only if selected for display |
| 7333 |
if(this->InternalMesh != NULL) |
| 7334 |
{ |
| 7335 |
#if PARAVIEW_VERSION_MAJOR >= 3 && PARAVIEW_VERSION_MINOR >= 3 |
| 7336 |
eulerians->SetBlock(0, this->InternalMesh); |
| 7337 |
this->SetBlockName(eulerians, 0, this->InternalMesh); |
| 7338 |
#else |
| 7339 |
output->SetDataSet(0, output->GetNumberOfDataSets(0), this->InternalMesh); |
| 7340 |
#endif |
| 7341 |
} |
| 3290 |
|
7342 |
|
| 3291 |
//erronous cells |
7343 |
// set boundary meshes/data as output |
| 3292 |
else if(totalPointCount == 0) |
7344 |
for(size_t j = 0; j < this->BoundaryMesh->size(); j++) |
|
|
7345 |
{ |
| 7346 |
#if PARAVIEW_VERSION_MAJOR >= 3 && PARAVIEW_VERSION_MINOR >= 3 |
| 7347 |
const unsigned int dataSetI = eulerians->GetNumberOfBlocks(); |
| 7348 |
eulerians->SetBlock(dataSetI, this->BoundaryMesh->operator[](j)); |
| 7349 |
this->SetBlockName(eulerians, dataSetI, this->BoundaryMesh->operator[](j)); |
| 7350 |
#else |
| 7351 |
output->SetDataSet(0, output->GetNumberOfDataSets(0), |
| 7352 |
this->BoundaryMesh->operator[](j)); |
| 7353 |
#endif |
| 7354 |
} |
| 7355 |
|
| 7356 |
#if PARAVIEW_VERSION_MAJOR >= 3 && PARAVIEW_VERSION_MINOR >= 3 |
| 7357 |
output->SetBlock(0, eulerians); |
| 7358 |
output->GetMetaData(static_cast<unsigned int>(0)) |
| 7359 |
->Set(vtkCompositeDataSet::NAME(), "Vol/Point Data"); |
| 7360 |
eulerians->Delete(); |
| 7361 |
#else |
| 7362 |
int groupI = 1; |
| 7363 |
#endif |
| 7364 |
|
| 7365 |
// set lagrangian mesh as output |
| 7366 |
if(lagrangianMesh->size() > 0) |
| 7367 |
{ |
| 7368 |
#if PARAVIEW_VERSION_MAJOR >= 3 && PARAVIEW_VERSION_MINOR >= 3 |
| 7369 |
vtkMultiBlockDataSet *lagrangians = vtkMultiBlockDataSet::New(); |
| 7370 |
#endif |
| 7371 |
for(size_t meshI = 0; meshI < lagrangianMesh->size(); meshI++) |
| 3293 |
{ |
7372 |
{ |
| 3294 |
vtkWarningMacro("Warning: No points in cell."); |
7373 |
#if PARAVIEW_VERSION_MAJOR >= 3 && PARAVIEW_VERSION_MINOR >= 3 |
|
|
7374 |
lagrangians->SetBlock(meshI, lagrangianMesh->operator[](meshI)); |
| 7375 |
this->SetBlockName(lagrangians, meshI, lagrangianMesh->operator[](meshI)); |
| 7376 |
#else |
| 7377 |
output->SetDataSet(groupI, output->GetNumberOfDataSets(groupI), |
| 7378 |
lagrangianMesh->operator[](meshI)); |
| 7379 |
#endif |
| 3295 |
} |
7380 |
} |
|
|
7381 |
#if PARAVIEW_VERSION_MAJOR >= 3 && PARAVIEW_VERSION_MINOR >= 3 |
| 7382 |
const unsigned int groupTypeI = output->GetNumberOfBlocks(); |
| 7383 |
output->SetBlock(groupTypeI, lagrangians); |
| 7384 |
output->GetMetaData(groupTypeI) |
| 7385 |
->Set(vtkCompositeDataSet::NAME(), "Lagrangian Particles"); |
| 7386 |
lagrangians->Delete(); |
| 7387 |
#else |
| 7388 |
groupI++; |
| 7389 |
#endif |
| 7390 |
} |
| 7391 |
delete lagrangianMesh; |
| 3296 |
|
7392 |
|
| 3297 |
//OFpolyhedron || vtkConvexPointSet |
7393 |
if(this->ReadZones) |
| 3298 |
else |
7394 |
{ |
|
|
7395 |
#if PARAVIEW_VERSION_MAJOR >= 3 && PARAVIEW_VERSION_MINOR >= 3 |
| 7396 |
vtkMultiBlockDataSet *zones = NULL; |
| 7397 |
#endif |
| 7398 |
// set Zone Meshes as output |
| 7399 |
if(this->PointZoneMesh != NULL) |
| 3299 |
{ |
7400 |
{ |
| 3300 |
vtkWarningMacro("Warning: Polyhedral Data is very Slow!"); |
7401 |
#if PARAVIEW_VERSION_MAJOR >= 3 && PARAVIEW_VERSION_MINOR >= 3 |
| 3301 |
foundDup = false; |
7402 |
if(zones == NULL) |
| 3302 |
|
7403 |
{ |
| 3303 |
//grab face 0 |
7404 |
zones = vtkMultiBlockDataSet::New(); |
| 3304 |
for(j = 0; j < (int)this->FacePoints->value[this->FacesOfCell->value[ |
7405 |
} |
| 3305 |
cellZone[i]][0].faceIndex].size(); j++) |
7406 |
vtkMultiBlockDataSet *pointZone = vtkMultiBlockDataSet::New(); |
|
|
7407 |
#endif |
| 7408 |
for(size_t i = 0; i < this->PointZoneMesh->size(); i++) |
| 3306 |
{ |
7409 |
{ |
| 3307 |
firstFace.push_back(this->FacePoints->value[ |
7410 |
#if PARAVIEW_VERSION_MAJOR >= 3 && PARAVIEW_VERSION_MINOR >= 3 |
| 3308 |
this->FacesOfCell->value[i][0].faceIndex][j]); |
7411 |
const unsigned int zoneI = pointZone->GetNumberOfBlocks(); |
|
|
7412 |
vtkDataObject *zoneMeshI = this->PointZoneMesh->operator[](i); |
| 7413 |
pointZone->SetBlock(zoneI, zoneMeshI); |
| 7414 |
this->SetBlockName(pointZone, zoneI, zoneMeshI); |
| 7415 |
#else |
| 7416 |
output->SetDataSet(groupI, output->GetNumberOfDataSets(groupI), |
| 7417 |
this->PointZoneMesh->operator[](i)); |
| 7418 |
#endif |
| 3309 |
} |
7419 |
} |
|
|
7420 |
#if PARAVIEW_VERSION_MAJOR >= 3 && PARAVIEW_VERSION_MINOR >= 3 |
| 7421 |
const unsigned int zoneTypeI = zones->GetNumberOfBlocks(); |
| 7422 |
zones->SetBlock(zoneTypeI, pointZone); |
| 7423 |
this->SetBlockName(zones, zoneTypeI, "pointZones"); |
| 7424 |
pointZone->Delete(); |
| 7425 |
#else |
| 7426 |
groupI++; |
| 7427 |
#endif |
| 7428 |
} |
| 3310 |
|
7429 |
|
| 3311 |
//ADD FIRST FACE TO CELL POINTS |
7430 |
if(this->FaceZoneMesh != NULL) |
| 3312 |
for(j =0; j < (int)firstFace.size(); j++) |
7431 |
{ |
| 3313 |
{ |
7432 |
#if PARAVIEW_VERSION_MAJOR >= 3 && PARAVIEW_VERSION_MINOR >= 3 |
| 3314 |
cellPoints.push_back(firstFace[j]); |
7433 |
if(zones == NULL) |
| 3315 |
} |
7434 |
{ |
| 3316 |
//j = 1 skip firstFace |
7435 |
zones = vtkMultiBlockDataSet::New(); |
| 3317 |
for(j = 1; j < (int) this->FacesOfCell->value[ |
7436 |
} |
| 3318 |
cellZone[i]].size(); j++) |
7437 |
vtkMultiBlockDataSet *faceZone = vtkMultiBlockDataSet::New(); |
| 3319 |
{ |
7438 |
#endif |
| 3320 |
//remove duplicate points from faces |
7439 |
for(size_t i = 0; i < this->FaceZoneMesh->size(); i++) |
| 3321 |
for(k = 0; k < (int)this->FacePoints->value[ |
7440 |
{ |
| 3322 |
this->FacesOfCell->value[i][j].faceIndex].size(); k++) |
7441 |
#if PARAVIEW_VERSION_MAJOR >= 3 && PARAVIEW_VERSION_MINOR >= 3 |
| 3323 |
{ |
7442 |
const unsigned int zoneI = faceZone->GetNumberOfBlocks(); |
| 3324 |
for(l = 0; l < (int)cellPoints.size(); l++); |
7443 |
vtkDataObject *zoneMeshI = this->FaceZoneMesh->operator[](i); |
| 3325 |
{ |
7444 |
faceZone->SetBlock(zoneI, zoneMeshI); |
| 3326 |
if(cellPoints[l] == this->FacePoints->value[this->FacesOfCell-> |
7445 |
this->SetBlockName(faceZone, zoneI, zoneMeshI); |
| 3327 |
value[cellZone[i]][j].faceIndex][k]) |
7446 |
#else |
| 3328 |
{ |
7447 |
output->SetDataSet(groupI, output->GetNumberOfDataSets(groupI), |
| 3329 |
foundDup = true; |
7448 |
this->FaceZoneMesh->operator[](i)); |
| 3330 |
} |
7449 |
#endif |
| 3331 |
} |
|
|
| 3332 |
if(!foundDup) |
| 3333 |
{ |
| 3334 |
cellPoints.push_back(this->FacePoints->value[this->FacesOfCell-> |
| 3335 |
value[cellZone[i]][j].faceIndex][k]); |
| 3336 |
foundDup = false; |
| 3337 |
} |
| 3338 |
} |
| 3339 |
} |
7450 |
} |
|
|
7451 |
#if PARAVIEW_VERSION_MAJOR >= 3 && PARAVIEW_VERSION_MINOR >= 3 |
| 7452 |
const unsigned int zoneTypeI = zones->GetNumberOfBlocks(); |
| 7453 |
zones->SetBlock(zoneTypeI, faceZone); |
| 7454 |
this->SetBlockName(zones, zoneTypeI, "faceZones"); |
| 7455 |
faceZone->Delete(); |
| 7456 |
#else |
| 7457 |
groupI++; |
| 7458 |
#endif |
| 7459 |
} |
| 3340 |
|
7460 |
|
| 3341 |
//create the poly cell and insert it into the mesh |
7461 |
if(this->CellZoneMesh != NULL) |
| 3342 |
vtkConvexPointSet * poly = vtkConvexPointSet::New(); |
7462 |
{ |
| 3343 |
poly->GetPointIds()->SetNumberOfIds(cellPoints.size()); |
7463 |
#if PARAVIEW_VERSION_MAJOR >= 3 && PARAVIEW_VERSION_MINOR >= 3 |
| 3344 |
for(pCount = 0; pCount < (int)cellPoints.size(); pCount++) |
7464 |
if(zones == NULL) |
| 3345 |
{ |
7465 |
{ |
| 3346 |
poly->GetPointIds()->SetId(pCount, cellPoints[pCount]); |
7466 |
zones = vtkMultiBlockDataSet::New(); |
| 3347 |
} |
7467 |
} |
| 3348 |
cellZoneMesh->InsertNextCell(poly->GetCellType(), |
7468 |
vtkMultiBlockDataSet *cellZone = vtkMultiBlockDataSet::New(); |
| 3349 |
poly->GetPointIds()); |
7469 |
#endif |
| 3350 |
cellPoints.clear(); |
7470 |
for(size_t i = 0; i < this->CellZoneMesh->size(); i++) |
| 3351 |
firstFace.clear(); |
7471 |
{ |
| 3352 |
poly->Delete(); |
7472 |
#if PARAVIEW_VERSION_MAJOR >= 3 && PARAVIEW_VERSION_MINOR >= 3 |
|
|
7473 |
const unsigned int zoneI = cellZone->GetNumberOfBlocks(); |
| 7474 |
vtkDataObject *zoneMeshI = this->CellZoneMesh->operator[](i); |
| 7475 |
cellZone->SetBlock(zoneI, zoneMeshI); |
| 7476 |
this->SetBlockName(cellZone, zoneI, zoneMeshI); |
| 7477 |
#else |
| 7478 |
output->SetDataSet(groupI, output->GetNumberOfDataSets(groupI), |
| 7479 |
this->CellZoneMesh->operator[](i)); |
| 7480 |
#endif |
| 7481 |
} |
| 7482 |
#if PARAVIEW_VERSION_MAJOR >= 3 && PARAVIEW_VERSION_MINOR >= 3 |
| 7483 |
const unsigned int zoneTypeI = zones->GetNumberOfBlocks(); |
| 7484 |
zones->SetBlock(zoneTypeI, cellZone); |
| 7485 |
this->SetBlockName(zones, zoneTypeI, "cellZones"); |
| 7486 |
cellZone->Delete(); |
| 7487 |
#endif |
| 7488 |
} |
| 7489 |
#if PARAVIEW_VERSION_MAJOR >= 3 && PARAVIEW_VERSION_MINOR >= 3 |
| 7490 |
if(zones != NULL) |
| 7491 |
{ |
| 7492 |
const unsigned int groupTypeI = output->GetNumberOfBlocks(); |
| 7493 |
output->SetBlock(groupTypeI, zones); |
| 7494 |
this->SetBlockName(output, groupTypeI, "Zones"); |
| 3353 |
} |
7495 |
} |
|
|
7496 |
#endif |
| 3354 |
} |
7497 |
} |
| 3355 |
//set cell zone points |
|
|
| 3356 |
cellZoneMesh->SetPoints(Points); |
| 3357 |
input->close(); |
| 3358 |
delete input; |
| 3359 |
vtkDebugMacro(<<"Cell zone mesh created"); |
| 3360 |
return cellZoneMesh; |
| 3361 |
} |
| 3362 |
|
7498 |
|
| 3363 |
void vtkOpenFOAMReader::CreateDataSet(vtkMultiBlockDataSet *output) |
7499 |
if(this->CacheMesh) |
| 3364 |
{ |
7500 |
{ |
| 3365 |
int timeState = this->TimeStep; |
7501 |
this->TimeStepOld = timeState; |
| 3366 |
//create paths to polyMesh files |
|
|
| 3367 |
vtkstd::string boundaryPath = this->PathPrefix->value + |
| 3368 |
this->PolyMeshFacesDir->value[timeState] + |
| 3369 |
"/polyMesh/boundary"; |
| 3370 |
vtkstd::string facePath = this->PathPrefix->value + |
| 3371 |
this->PolyMeshFacesDir->value[timeState] + |
| 3372 |
"/polyMesh/faces"; |
| 3373 |
vtkstd::string ownerPath = this->PathPrefix->value + |
| 3374 |
this->PolyMeshFacesDir->value[timeState] + |
| 3375 |
"/polyMesh/owner"; |
| 3376 |
vtkstd::string neighborPath = this->PathPrefix->value + |
| 3377 |
this->PolyMeshFacesDir->value[timeState] + |
| 3378 |
"/polyMesh/neighbour"; |
| 3379 |
//create the faces vector |
| 3380 |
this->ReadFacesFile(facePath.c_str()); |
| 3381 |
|
| 3382 |
//create the faces owner vector |
| 3383 |
this->ReadOwnerFile(ownerPath.c_str()); |
| 3384 |
|
| 3385 |
//create the faces neighbor vector |
| 3386 |
this->ReadNeighborFile(neighborPath.c_str()); |
| 3387 |
|
| 3388 |
//create a vector containing a faces of each cell |
| 3389 |
this->CombineOwnerNeigbor(); |
| 3390 |
|
| 3391 |
this->GetPoints(timeState); //get the points |
| 3392 |
|
| 3393 |
//get the names of the regions |
| 3394 |
//this->BoundaryNames->value = |
| 3395 |
// this->GatherBlocks("boundary", timeState)->value; |
| 3396 |
//this->PointZoneNames->value = |
| 3397 |
// this->GatherBlocks("pointZones", timeState)->value; |
| 3398 |
//this->FaceZoneNames->value = |
| 3399 |
// this->GatherBlocks("faceZones", timeState)->value; |
| 3400 |
//this->CellZoneNames->value = |
| 3401 |
// this->GatherBlocks("cellZones", timeState)->value; |
| 3402 |
|
| 3403 |
//get the names of the regions |
| 3404 |
this->BoundaryNames = |
| 3405 |
this->GatherBlocks("boundary", timeState); |
| 3406 |
this->PointZoneNames = |
| 3407 |
this->GatherBlocks("pointZones", timeState); |
| 3408 |
this->FaceZoneNames = |
| 3409 |
this->GatherBlocks("faceZones", timeState); |
| 3410 |
this->CellZoneNames = |
| 3411 |
this->GatherBlocks("cellZones", timeState); |
| 3412 |
|
| 3413 |
int numBoundaries = static_cast<int>(this->BoundaryNames->value.size()); |
| 3414 |
int numPointZones = static_cast<int>(this->PointZoneNames->value.size()); |
| 3415 |
int numFaceZones = static_cast<int>(this->FaceZoneNames->value.size()); |
| 3416 |
int numCellZones = static_cast<int>(this->CellZoneNames->value.size()); |
| 3417 |
|
| 3418 |
//Internal Mesh |
| 3419 |
vtkUnstructuredGrid * internalMesh = this->MakeInternalMesh(); |
| 3420 |
for(int i = 0; i < (int)this->TimeStepData->value.size(); i++) |
| 3421 |
{ |
| 3422 |
vtkDoubleArray * data = |
| 3423 |
this->GetInternalVariableAtTimestep(this->TimeStepData->value[i].c_str(), |
| 3424 |
timeState); |
| 3425 |
if(data->GetSize() > 0) |
| 3426 |
{ |
| 3427 |
data->SetName(this->TimeStepData->value[i].c_str()); |
| 3428 |
internalMesh->GetCellData()->AddArray(data); |
| 3429 |
} |
| 3430 |
data->Delete(); |
| 3431 |
} |
| 3432 |
output->SetBlock(output->GetNumberOfBlocks(), internalMesh); |
| 3433 |
|
| 3434 |
//Boundary Meshes |
| 3435 |
for(int i = 0; i < (int)numBoundaries; i++) |
| 3436 |
{ |
| 3437 |
vtkUnstructuredGrid * boundaryMesh = this->GetBoundaryMesh(timeState, i); |
| 3438 |
for(int j = 0; j < (int)this->TimeStepData->value.size(); j++) |
| 3439 |
{ |
| 3440 |
vtkDoubleArray * data = |
| 3441 |
this->GetBoundaryVariableAtTimestep(i, TimeStepData->value[j].c_str(), |
| 3442 |
timeState, internalMesh); |
| 3443 |
if(data->GetSize() > 0) |
| 3444 |
{ |
| 3445 |
data->SetName(this->TimeStepData->value[j].c_str()); |
| 3446 |
boundaryMesh->GetCellData()->AddArray(data); |
| 3447 |
} |
| 3448 |
data->Delete(); |
| 3449 |
} |
| 3450 |
output->SetBlock(output->GetNumberOfBlocks(), boundaryMesh); |
| 3451 |
boundaryMesh->Delete(); |
| 3452 |
} |
| 3453 |
|
| 3454 |
internalMesh->Delete(); |
| 3455 |
this->FaceOwner->Delete(); |
| 3456 |
//Zone Meshes |
| 3457 |
for(int i = 0; i < (int)numPointZones; i++) |
| 3458 |
{ |
| 3459 |
vtkUnstructuredGrid * pointMesh = this->GetPointZoneMesh(timeState, i); |
| 3460 |
output->SetBlock(output->GetNumberOfBlocks(), pointMesh); |
| 3461 |
pointMesh->Delete(); |
| 3462 |
} |
| 3463 |
for(int i = 0; i < (int)numFaceZones; i++) |
| 3464 |
{ |
| 3465 |
vtkUnstructuredGrid * faceMesh = this->GetFaceZoneMesh(timeState, i); |
| 3466 |
output->SetBlock(output->GetNumberOfBlocks(), faceMesh); |
| 3467 |
faceMesh->Delete(); |
| 3468 |
} |
| 3469 |
for(int i = 0; i < (int)numCellZones; i++) |
| 3470 |
{ |
| 3471 |
vtkUnstructuredGrid * cellMesh = this->GetCellZoneMesh(timeState, i); |
| 3472 |
output->SetBlock(output->GetNumberOfBlocks(), cellMesh); |
| 3473 |
cellMesh->Delete(); |
| 3474 |
} |
7502 |
} |
| 3475 |
return; |
7503 |
else |
| 3476 |
} |
|
|
| 3477 |
stdString * vtkOpenFOAMReader::GetLine(ifstream * file) |
| 3478 |
{ |
| 3479 |
char tempChar; |
| 3480 |
stdString * buffer = new stdString; |
| 3481 |
while(file->peek() != '\n') |
| 3482 |
{ |
7504 |
{ |
| 3483 |
file->get(tempChar); |
7505 |
this->ClearMeshes(); |
| 3484 |
buffer->value += tempChar; |
7506 |
this->TimeStepOld = -1; |
| 3485 |
} |
7507 |
} |
| 3486 |
file->get(tempChar); //throw out \n |
7508 |
|
| 3487 |
return buffer; |
7509 |
this->UpdateProgress(1.0); |
|
|
7510 |
return 1; |
| 3488 |
} |
7511 |
} |