00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef VTK_FIELD_DRIVER_HXX
00024 #define VTK_FIELD_DRIVER_HXX
00025
00026 #include <string>
00027 #include <fstream>
00028 #include <sstream>
00029
00030 #include "MEDMEM_define.hxx"
00031
00032 #include "MEDMEM_GenDriver.hxx"
00033 #include "MEDMEM_Utilities.hxx"
00034
00035 #include "MEDMEM_STRING.hxx"
00036 #include "MEDMEM_Exception.hxx"
00037 #include "MEDMEM_Unit.hxx"
00038 #include "MEDMEM_nArray.hxx"
00039 #include "MEDMEM_ArrayConvert.hxx"
00040 #include "MEDMEM_Support.hxx"
00041 #include "MEDMEM_Mesh.hxx"
00042 #include "MEDMEM_CellModel.hxx"
00043 #include "MEDMEM_VtkMeshDriver.hxx"
00044
00045 #ifdef WNT
00046 #include <io.h>
00047 #else
00048 #include <unistd.h>
00049 #endif
00050 #include <fcntl.h>
00051
00060 namespace MEDMEM {
00061 template <class T> class VTK_FIELD_DRIVER : public GENDRIVER
00062 {
00063 protected:
00064
00065 const FIELD<T> * _ptrField;
00066 std::string _fieldName;
00067 int _fieldNum;
00068
00069 mutable ofstream * _vtkFile ;
00070 mutable _VTK_BinaryWriter* _binaryFile;
00071
00072 public :
00073
00077 VTK_FIELD_DRIVER():GENDRIVER(VTK_DRIVER),
00078 _ptrField(0), _fieldName(""), _fieldNum(MED_EN::MED_INVALID),
00079 _vtkFile(0), _binaryFile(0)
00080 {
00081 const char * LOC = "VTK_FIELD_DRIVER::VTK_FIELD_DRIVER() ";
00082 BEGIN_OF_MED(LOC);
00083 END_OF_MED(LOC);
00084 }
00088 template <class INTERLACING_TAG>
00089 VTK_FIELD_DRIVER(const std::string & fileName,
00090 const FIELD<T, INTERLACING_TAG> * ptrField):
00091 GENDRIVER(fileName, MED_EN::WRONLY, VTK_DRIVER),
00092 _ptrField((const FIELD<T> *) ptrField), _fieldName(fileName),_fieldNum(MED_EN::MED_INVALID),
00093 _vtkFile(0), _binaryFile(0)
00094 {
00095 const char* LOC = "VTK_FIELD_DRIVER::VTK_FIELD_DRIVER(const string & fileName, FIELD<T> * ptrField) ";
00096 BEGIN_OF_MED(LOC);
00097 END_OF_MED(LOC);
00098 }
00099
00103 VTK_FIELD_DRIVER(const VTK_FIELD_DRIVER & fieldDriver):
00104 GENDRIVER(fieldDriver),
00105 _ptrField(fieldDriver._ptrField),
00106 _fieldName(fieldDriver._fieldName),
00107 _fieldNum(fieldDriver._fieldNum),
00108 _vtkFile(0), _binaryFile(0)
00109 {
00110 }
00111
00115 ~VTK_FIELD_DRIVER()
00116 {
00117 const char* LOC = "VTK_FIELD_DRIVER::~VTK_FIELD_DRIVER()";
00118 BEGIN_OF_MED(LOC);
00119
00120 close();
00121
00122 if ( _vtkFile ) delete _vtkFile ;
00123 if ( _binaryFile ) delete _binaryFile;
00124
00125 _vtkFile = 0;
00126 _binaryFile = 0;
00127
00128 END_OF_MED(LOC);
00129 }
00130
00131 void openConst(bool append=false) const throw (MEDEXCEPTION)
00132 {
00133 const char * LOC = "VTK_FIELD_DRIVER::openConst()" ;
00134 BEGIN_OF_MED(LOC);
00135
00136 if ( _fileName == "" )
00137 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
00138 << "_fileName is |\"\"|, please set a correct fileName before calling open()"));
00139
00140 if ( DRIVERFACTORY::getVtkBinaryFormatForWriting() )
00141 {
00142 if ( _vtkFile )
00143 {
00144 closeConst();
00145 delete _vtkFile;
00146 _vtkFile = 0;
00147 }
00148 if ( !_binaryFile )
00149 _binaryFile = new _VTK_BinaryWriter( _fileName );
00150 else
00151 _binaryFile->close();
00152 if (!_binaryFile->open(append))
00153 {
00154 delete _binaryFile;
00155 _binaryFile = 0;
00156 throw MED_EXCEPTION( LOCALIZED( STRING(LOC) << "Could not open file "<< _fileName));
00157 }
00158 }
00159 else
00160 {
00161 if ( _binaryFile )
00162 {
00163 _binaryFile->close();
00164 delete _binaryFile;
00165 _binaryFile = 0;
00166 }
00167
00168 if (!_vtkFile )
00169 _vtkFile = new ofstream();
00170 else
00171 (*_vtkFile).close();
00172
00173 if ( append )
00174 (*_vtkFile).open(_fileName.c_str(), ofstream::out | ofstream::app);
00175 else
00176 (*_vtkFile).open(_fileName.c_str());
00177
00178 if (!(*_vtkFile))
00179 {
00180 delete _vtkFile;
00181 _vtkFile = 0;
00182 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not open file "<< _fileName));
00183 }
00184 }
00185 END_OF_MED(LOC);
00186 }
00187
00188 void openConstAppend() const throw (MEDEXCEPTION)
00189 {
00190 openConst(true);
00191 }
00192
00193 void open() throw (MEDEXCEPTION)
00194 {
00195 openConst() ;
00196 }
00197
00198 void openAppend() throw (MEDEXCEPTION)
00199 {
00200 openConst(true) ;
00201 }
00202
00203 void closeConst() const throw (MEDEXCEPTION)
00204 {
00205 const char * LOC = "VTK_FIELD_DRIVER::closeConst() " ;
00206 BEGIN_OF_MED(LOC);
00207
00208 if ( _vtkFile )
00209 {
00210 if ((*_vtkFile).is_open())
00211 (*_vtkFile).close();
00212
00213 if ( (*_vtkFile) && _vtkFile->is_open() )
00214 throw MED_EXCEPTION( LOCALIZED( STRING(LOC) << "Could not close file "<< _fileName));
00215 }
00216 if ( _binaryFile )
00217 {
00218 _binaryFile->close();
00219 delete _binaryFile;
00220 _binaryFile = 0;
00221 }
00222
00223 END_OF_MED(LOC);
00224 }
00225
00226 void close() {
00227 closeConst() ;
00228 }
00229
00235 void setFieldName(const string & fieldName) ;
00236
00240 string getFieldName() const ;
00241
00245 void read ( void ) throw (MEDEXCEPTION) ;
00246
00252 void write( void ) const throw (MEDEXCEPTION) ;
00253
00259 void writeAppend( void ) const throw (MEDEXCEPTION);
00260
00261 private:
00262 GENDRIVER * copy ( void ) const ;
00263
00264 };
00265
00266
00267
00268
00269
00270
00271
00272 template <class T> void VTK_FIELD_DRIVER<T>::setFieldName(const string & fieldName)
00273 {
00274 _fieldName = fieldName;
00275 }
00276
00277 template <class T> string VTK_FIELD_DRIVER<T>::getFieldName() const
00278 {
00279 return _fieldName;
00280 }
00281
00282 template <class T> GENDRIVER * VTK_FIELD_DRIVER<T>::copy(void) const
00283 {
00284 VTK_FIELD_DRIVER<T> * myDriver = new VTK_FIELD_DRIVER<T>(*this);
00285
00286 return myDriver ;
00287 }
00288
00289 template <class T> void VTK_FIELD_DRIVER<T>::read (void)
00290 throw (MEDEXCEPTION)
00291 {
00292 throw MEDEXCEPTION("VTK_FIELD_DRIVER::read : Can't read with a VTK driver because it is write only driver !");
00293 }
00294
00295
00299
00300
00301 template <class T> void VTK_FIELD_DRIVER<T>::write(void) const
00302 throw (MEDEXCEPTION)
00303 {
00304 const char * LOC = "VTK_FIELD_DRIVER::write(void) const " ;
00305 BEGIN_OF_MED(LOC);
00306
00307
00308
00309 const SUPPORT * supportField = _ptrField->getSupport();
00310 const GMESH * meshField = supportField->getMesh();
00311 if (! meshField )
00312 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": mesh was not read before writing")) ;
00313
00314
00315 {
00316 VTK_MESH_DRIVER meshDriver( _fileName, meshField );
00317 meshDriver.write();
00318 }
00319
00320
00321 writeAppend();
00322 }
00323
00324
00328
00329
00330 template <class T> void VTK_FIELD_DRIVER<T>::writeAppend(void) const
00331 throw (MEDEXCEPTION)
00332 {
00333 const char * LOC = "VTK_FIELD_DRIVER::writeAppend(void) const " ;
00334 BEGIN_OF_MED(LOC);
00335
00336
00337
00338 const SUPPORT * supportField = _ptrField->getSupport();
00339 const GMESH * meshField = supportField->getMesh();
00340 MED_EN::medEntityMesh entitySupport = supportField->getEntity();
00341
00342 if (! meshField )
00343 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": mesh was not read before writing")) ;
00344
00345 if ( _ptrField->getGaussPresence() )
00346 throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<<_ptrField->getName()<<" which use Gauss Points !" << entitySupport));
00347
00348 if (!(supportField->isOnAllElements()))
00349 throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<<_ptrField->getName()<<" which is not on all entities of the mesh !" << entitySupport));
00350
00351
00352
00353
00354 openConstAppend() ;
00355
00356
00357
00358
00359
00360
00361
00362 int dt = _ptrField->getIterationNumber();
00363 int it = _ptrField->getOrderNumber();
00364
00365 ostringstream name ;
00366 string nameField = _ptrField->getName();
00367 name << nameField << "_" << dt << "_" << it ;
00368
00369
00370
00371 STRING dataStr;
00372 if (entitySupport == MED_EN::MED_NODE)
00373 dataStr << "POINT_DATA " << meshField->getNumberOfNodes() ;
00374 else if (entitySupport == MED_EN::MED_CELL)
00375 dataStr << "CELL_DATA " << meshField->getNumberOfElements(MED_EN::MED_CELL,MED_EN::MED_ALL_ELEMENTS);
00376 else
00377 throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<<_ptrField->getName()<<" which is not on all nodes or cells but it's on !" << entitySupport));
00378
00379
00380 bool toWriteDataStr = true;
00381 #ifdef WNT
00382 int vtkFile = ::_open (_fileName.c_str(), _O_RDONLY|_O_BINARY);
00383 #else
00384 int vtkFile = ::open (_fileName.c_str(), O_RDONLY);
00385 #endif
00386 if ( vtkFile > 0 )
00387 {
00388 #ifdef WNT
00389 ssize_t fileSize = ::_lseek( vtkFile, 0, SEEK_END); ::lseek( vtkFile, 0, SEEK_SET);
00390 char* buf = new char[ fileSize ];
00391 ::_read (vtkFile, buf, fileSize );
00392 #else
00393 ssize_t fileSize = ::lseek( vtkFile, 0, SEEK_END); ::lseek( vtkFile, 0, SEEK_SET);
00394 char* buf = new char[ fileSize ];
00395 ::read (vtkFile, buf, fileSize );
00396 #endif
00397 char *vtkData = buf, *vtkDataEnd = buf+fileSize-dataStr.size();
00398 while ( ++vtkData < vtkDataEnd && toWriteDataStr )
00399 toWriteDataStr = ( strncmp( dataStr.data(), vtkData, dataStr.size()) != 0 );
00400 delete [] buf;
00401 #ifdef WNT
00402 ::_close (vtkFile);
00403 #else
00404 ::close (vtkFile);
00405 #endif
00406 }
00407 std::ostringstream vtkFileStr;
00408 if ( _binaryFile )
00409 vtkFileStr << endl;
00410 if ( toWriteDataStr )
00411 vtkFileStr << dataStr << endl;
00412
00413
00414 int NomberOfValue = supportField->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS) ;
00415 int NomberOfComponents = _ptrField->getNumberOfComponents() ;
00416
00417 MED_EN::med_type_champ fieldType = _ptrField->getValueType() ;
00418
00419 SCRUTE_MED(name.str());
00420 SCRUTE_MED(fieldType);
00421
00422 std::string typeStr;
00423 switch (fieldType)
00424 {
00425 case MED_EN::MED_INT32 :
00426 {
00427 typeStr = " int"; break ;
00428 }
00429 case MED_EN::MED_REEL64 :
00430 {
00431 typeStr = " float"; break ;
00432 }
00433 default :
00434 {
00435 throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<< name.str() <<" the type is not int or double !"));
00436 }
00437 }
00438
00439 if (NomberOfComponents==3)
00440 vtkFileStr << "VECTORS " << name.str() << typeStr << endl ;
00441 else if (NomberOfComponents<=4)
00442 {
00443 vtkFileStr << "SCALARS " << name.str() << typeStr << " " << NomberOfComponents << endl ;
00444 vtkFileStr << "LOOKUP_TABLE default" << endl ;
00445 }
00446 else
00447 throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<<_ptrField->getName()<<" there are more than 4 components !"));
00448
00449 const T * value ;
00450 MEDMEM_Array_ * tmpArray = 0;
00451 if ( _ptrField->getInterlacingType() == MED_EN::MED_FULL_INTERLACE )
00452 {
00453 value = _ptrField->getValue();
00454 }
00455 else if ( _ptrField->getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE )
00456 {
00457 MEDMEM_Array_ * ptrArray = _ptrField->getArray();
00458 MEDMEM_Array<T,NoInterlaceByTypeNoGaussPolicy> * temp = dynamic_cast<MEDMEM_Array<T,NoInterlaceByTypeNoGaussPolicy> * > ( ptrArray );
00459 MEDMEM_Array<T,NoInterlaceNoGaussPolicy> * array = ArrayConvert2No( *temp );
00460 tmpArray = array;
00461 value = array->getPtr();
00462 }
00463 else
00464 {
00465 MEDMEM_Array_ * ptrArray = _ptrField->getArray();
00466 MEDMEM_Array<T,NoInterlaceNoGaussPolicy> * temp = dynamic_cast<MEDMEM_Array<T,NoInterlaceNoGaussPolicy> * > ( ptrArray );
00467 MEDMEM_Array<T,FullInterlaceNoGaussPolicy> * array = ArrayConvert( *temp );
00468 tmpArray = array;
00469 value = array->getPtr();
00470 }
00471
00472 if ( _vtkFile )
00473 {
00474 (*_vtkFile) << vtkFileStr.str();
00475 for (int i=0; i<NomberOfValue; i++)
00476 {
00477 for(int j=0; j<NomberOfComponents; j++)
00478 (*_vtkFile) << value[j*NomberOfValue+i] << " " ;
00479 (*_vtkFile) << endl ;
00480 }
00481 }
00482 else
00483 {
00484 std::string str = vtkFileStr.str();
00485 _binaryFile->write( str.data(), str.size() );
00486
00487
00488 if ( fieldType == MED_EN::MED_REEL64 )
00489 {
00490 vector<float> floatValue(NomberOfValue * NomberOfComponents );
00491 for ( unsigned i = 0; i < floatValue.size(); ++i )
00492 floatValue[i]=float( value[i] );
00493 _binaryFile->write( &floatValue[0], NomberOfValue * NomberOfComponents );
00494 }
00495 else
00496 {
00497 _binaryFile->write( value, NomberOfValue * NomberOfComponents );
00498 }
00499 }
00500
00501 if ( _ptrField->getInterlacingType() != MED_EN::MED_FULL_INTERLACE )
00502 delete tmpArray;
00503
00504 closeConst();
00505
00506 END_OF_MED(LOC);
00507 }
00508 }
00509
00510 #endif