1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #ifndef VTK_FIELD_DRIVER_HXX
24 #define VTK_FIELD_DRIVER_HXX
30 #include "MEDMEM_define.hxx"
32 #include "MEDMEM_GenDriver.hxx"
33 #include "MEDMEM_Utilities.hxx"
35 #include "MEDMEM_STRING.hxx"
36 #include "MEDMEM_Exception.hxx"
37 #include "MEDMEM_Unit.hxx"
38 #include "MEDMEM_nArray.hxx"
39 #include "MEDMEM_ArrayConvert.hxx"
40 #include "MEDMEM_Support.hxx"
41 #include "MEDMEM_Mesh.hxx"
42 #include "MEDMEM_CellModel.hxx"
43 #include "MEDMEM_VtkMeshDriver.hxx"
56 Generic part : implement open and close methods.
61 template <class T> class VTK_FIELD_DRIVER : public GENDRIVER
65 const FIELD<T> * _ptrField;
66 std::string _fieldName;
69 mutable ofstream * _vtkFile ;
70 mutable _VTK_BinaryWriter* _binaryFile;
77 VTK_FIELD_DRIVER():GENDRIVER(VTK_DRIVER),
78 _ptrField(0), _fieldName(""), _fieldNum(MED_EN::MED_INVALID),
79 _vtkFile(0), _binaryFile(0)
81 const char * LOC = "VTK_FIELD_DRIVER::VTK_FIELD_DRIVER() ";
88 template <class INTERLACING_TAG>
89 VTK_FIELD_DRIVER(const std::string & fileName,
90 const FIELD<T, INTERLACING_TAG> * ptrField):
91 GENDRIVER(fileName, MED_EN::WRONLY, VTK_DRIVER),
92 _ptrField((const FIELD<T> *) ptrField), _fieldName(fileName),_fieldNum(MED_EN::MED_INVALID),
93 _vtkFile(0), _binaryFile(0)
95 const char* LOC = "VTK_FIELD_DRIVER::VTK_FIELD_DRIVER(const string & fileName, FIELD<T> * ptrField) ";
103 VTK_FIELD_DRIVER(const VTK_FIELD_DRIVER & fieldDriver):
104 GENDRIVER(fieldDriver),
105 _ptrField(fieldDriver._ptrField),
106 _fieldName(fieldDriver._fieldName),
107 _fieldNum(fieldDriver._fieldNum),
108 _vtkFile(0), _binaryFile(0)
117 const char* LOC = "VTK_FIELD_DRIVER::~VTK_FIELD_DRIVER()";
122 if ( _vtkFile ) delete _vtkFile ;
123 if ( _binaryFile ) delete _binaryFile;
131 void openConst(bool append=false) const throw (MEDEXCEPTION)
133 const char * LOC = "VTK_FIELD_DRIVER::openConst()" ;
136 if ( _fileName == "" )
137 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
138 << "_fileName is |\"\"|, please set a correct fileName before calling open()"));
140 if ( DRIVERFACTORY::getVtkBinaryFormatForWriting() )
149 _binaryFile = new _VTK_BinaryWriter( _fileName );
151 _binaryFile->close();
152 if (!_binaryFile->open(append))
156 throw MED_EXCEPTION( LOCALIZED( STRING(LOC) << "Could not open file "<< _fileName));
163 _binaryFile->close();
169 _vtkFile = new ofstream();
174 (*_vtkFile).open(_fileName.c_str(), ofstream::out | ofstream::app);
176 (*_vtkFile).open(_fileName.c_str());
182 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not open file "<< _fileName));
188 void openConstAppend() const throw (MEDEXCEPTION)
193 void open() throw (MEDEXCEPTION)
198 void openAppend() throw (MEDEXCEPTION)
203 void closeConst() const throw (MEDEXCEPTION)
205 const char * LOC = "VTK_FIELD_DRIVER::closeConst() " ;
210 if ((*_vtkFile).is_open())
213 if ( (*_vtkFile) && _vtkFile->is_open() )
214 throw MED_EXCEPTION( LOCALIZED( STRING(LOC) << "Could not close file "<< _fileName));
218 _binaryFile->close();
231 Set the name of the FIELD asked in file.
233 It could be different than the name of the FIELD object.
235 void setFieldName(const string & fieldName) ;
238 Get the name of the FIELD asked in file.
240 string getFieldName() const ;
243 Return a MEDEXCEPTION : it is the write-only driver.
245 void read ( void ) throw (MEDEXCEPTION) ;
248 Write FIELD in the specified file, with its mesh through its support
249 which has to be on all entities (excluding the faces in 3d and edges
252 void write( void ) const throw (MEDEXCEPTION) ;
255 Write FIELD in the specified file, the mesh is supposed to be
256 written in this file. The field support has to be on all entities
257 (excluding the faces in 3d and edges in 2d).
259 void writeAppend( void ) const throw (MEDEXCEPTION);
262 GENDRIVER * copy ( void ) const ;
266 /*-------------------------*/
267 /* template implementation */
268 /*-------------------------*/
270 /*--------------------- DRIVER PART -------------------------------*/
272 template <class T> void VTK_FIELD_DRIVER<T>::setFieldName(const string & fieldName)
274 _fieldName = fieldName;
277 template <class T> string VTK_FIELD_DRIVER<T>::getFieldName() const
282 template <class T> GENDRIVER * VTK_FIELD_DRIVER<T>::copy(void) const
284 VTK_FIELD_DRIVER<T> * myDriver = new VTK_FIELD_DRIVER<T>(*this);
289 template <class T> void VTK_FIELD_DRIVER<T>::read (void)
292 throw MEDEXCEPTION("VTK_FIELD_DRIVER::read : Can't read with a VTK driver because it is write only driver !");
295 //================================================================================
299 //================================================================================
301 template <class T> void VTK_FIELD_DRIVER<T>::write(void) const
304 const char * LOC = "VTK_FIELD_DRIVER::write(void) const " ;
307 // we get the Support and its associated Mesh
309 const SUPPORT * supportField = _ptrField->getSupport();
310 const GMESH * meshField = supportField->getMesh();
312 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": mesh was not read before writing")) ;
316 VTK_MESH_DRIVER meshDriver( _fileName, meshField );
324 //================================================================================
326 * \brief Write append
328 //================================================================================
330 template <class T> void VTK_FIELD_DRIVER<T>::writeAppend(void) const
333 const char * LOC = "VTK_FIELD_DRIVER::writeAppend(void) const " ;
336 // we get the Support and its associated Mesh
338 const SUPPORT * supportField = _ptrField->getSupport();
339 const GMESH * meshField = supportField->getMesh();
340 MED_EN::medEntityMesh entitySupport = supportField->getEntity();
343 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": mesh was not read before writing")) ;
345 if ( _ptrField->getGaussPresence() )
346 throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<<_ptrField->getName()<<" which use Gauss Points !" << entitySupport));
348 if (!(supportField->isOnAllElements()))
349 throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<<_ptrField->getName()<<" which is not on all entities of the mesh !" << entitySupport));
352 // Well we must open vtk file first, because there are
353 // no other driver than MED for VTK that do it !
356 // first : field on node
357 // fields is on all node !
359 // second : field on cell
360 // fields is on all cell !
362 int dt = _ptrField->getIterationNumber();
363 int it = _ptrField->getOrderNumber();
366 string nameField = _ptrField->getName();
367 name << nameField << "_" << dt << "_" << it ;
369 // BEGIN issue 0020610: [CEA 371] VTK field driver : save many fields.
370 // POINT_DATA and CELL_DATA must encounters once
372 if (entitySupport == MED_EN::MED_NODE)
373 dataStr << "POINT_DATA " << meshField->getNumberOfNodes() ;
374 else if (entitySupport == MED_EN::MED_CELL)
375 dataStr << "CELL_DATA " << meshField->getNumberOfElements(MED_EN::MED_CELL,MED_EN::MED_ALL_ELEMENTS);
377 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));
379 // check if dataStr is already present in the file
380 bool toWriteDataStr = true;
382 int vtkFile = ::_open (_fileName.c_str(), _O_RDONLY|_O_BINARY);
384 int vtkFile = ::open (_fileName.c_str(), O_RDONLY);
389 ssize_t fileSize = ::_lseek( vtkFile, 0, SEEK_END); ::lseek( vtkFile, 0, SEEK_SET);
390 char* buf = new char[ fileSize ];
391 ::_read (vtkFile, buf, fileSize );
393 ssize_t fileSize = ::lseek( vtkFile, 0, SEEK_END); ::lseek( vtkFile, 0, SEEK_SET);
394 char* buf = new char[ fileSize ];
395 ::read (vtkFile, buf, fileSize );
397 char *vtkData = buf, *vtkDataEnd = buf+fileSize-dataStr.size();
398 while ( ++vtkData < vtkDataEnd && toWriteDataStr )
399 toWriteDataStr = ( strncmp( dataStr.data(), vtkData, dataStr.size()) != 0 );
407 std::ostringstream vtkFileStr; // to collect labels
410 if ( toWriteDataStr )
411 vtkFileStr << dataStr << endl;
412 // END issue 0020610: [CEA 371] VTK field driver : save many fields
414 int NomberOfValue = supportField->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS) ;
415 int NomberOfComponents = _ptrField->getNumberOfComponents() ;
417 MED_EN::med_type_champ fieldType = _ptrField->getValueType() ;
419 SCRUTE_MED(name.str());
420 SCRUTE_MED(fieldType);
425 case MED_EN::MED_INT32 :
427 typeStr = " int"; break ;
429 case MED_EN::MED_REEL64 :
431 typeStr = " float"; break ;
435 throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<< name.str() <<" the type is not int or double !"));
439 if (NomberOfComponents==3)
440 vtkFileStr << "VECTORS " << name.str() << typeStr << endl ;
441 else if (NomberOfComponents<=4)
443 vtkFileStr << "SCALARS " << name.str() << typeStr << " " << NomberOfComponents << endl ;
444 vtkFileStr << "LOOKUP_TABLE default" << endl ;
447 throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<<_ptrField->getName()<<" there are more than 4 components !"));
450 MEDMEM_Array_ * tmpArray = 0;
451 if ( _ptrField->getInterlacingType() == MED_EN::MED_FULL_INTERLACE )
453 value = _ptrField->getValue();
455 else if ( _ptrField->getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE )
457 MEDMEM_Array_ * ptrArray = _ptrField->getArray();
458 MEDMEM_Array<T,NoInterlaceByTypeNoGaussPolicy> * temp = dynamic_cast<MEDMEM_Array<T,NoInterlaceByTypeNoGaussPolicy> * > ( ptrArray );
459 MEDMEM_Array<T,NoInterlaceNoGaussPolicy> * array = ArrayConvert2No( *temp );
461 value = array->getPtr();
465 MEDMEM_Array_ * ptrArray = _ptrField->getArray();
466 MEDMEM_Array<T,NoInterlaceNoGaussPolicy> * temp = dynamic_cast<MEDMEM_Array<T,NoInterlaceNoGaussPolicy> * > ( ptrArray );
467 MEDMEM_Array<T,FullInterlaceNoGaussPolicy> * array = ArrayConvert( *temp );
469 value = array->getPtr();
472 if ( _vtkFile ) // ASCII
474 (*_vtkFile) << vtkFileStr.str();
475 for (int i=0; i<NomberOfValue; i++)
477 for(int j=0; j<NomberOfComponents; j++)
478 (*_vtkFile) << value[j*NomberOfValue+i] << " " ;
479 (*_vtkFile) << endl ;
484 std::string str = vtkFileStr.str();
485 _binaryFile->write( str.data(), str.size() );
486 // Though type "double" is available in VTK but actually it does not work
487 // (at least paraview shows wrong values)
488 if ( fieldType == MED_EN::MED_REEL64 )
490 vector<float> floatValue(NomberOfValue * NomberOfComponents );
491 for ( unsigned i = 0; i < floatValue.size(); ++i )
492 floatValue[i]=float( value[i] );
493 _binaryFile->write( &floatValue[0], NomberOfValue * NomberOfComponents );
497 _binaryFile->write( value, NomberOfValue * NomberOfComponents );
501 if ( _ptrField->getInterlacingType() != MED_EN::MED_FULL_INTERLACE )
508 }//End namespace MEDMEM
510 #endif /* VTK_FIELD_DRIVER_HXX */