1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/
20 #ifndef VTK_FIELD_DRIVER_HXX
21 #define VTK_FIELD_DRIVER_HXX
27 #include "MEDMEM_define.hxx"
29 #include "MEDMEM_GenDriver.hxx"
30 #include "MEDMEM_Utilities.hxx"
32 #include "MEDMEM_Exception.hxx"
33 #include "MEDMEM_Unit.hxx"
34 #include "MEDMEM_Array.hxx"
35 #include "MEDMEM_Support.hxx"
36 #include "MEDMEM_Mesh.hxx"
37 #include "MEDMEM_CellModel.hxx"
44 Generic part : implement open and close methods.
49 template <class T> class FIELD;
50 template <class T> class VTK_FIELD_DRIVER : public GENDRIVER
55 mutable ofstream * _vtkFile ;
61 // all MED cell type ?? Classe de Définition ??
62 // static const medGeometryElement all_cell_type[MED_NBR_GEOMETRIE_MAILLE];
64 // static const char * const all_cell_type_tab [MED_NBR_GEOMETRIE_MAILLE];
69 VTK_FIELD_DRIVER():GENDRIVER(),
70 _ptrField((FIELD<T> *) 0), _fieldName(""),
71 _fieldNum(MED_INVALID)
73 const char * LOC = "VTK_FIELD_DRIVER::VTK_FIELD_DRIVER() ";
76 _vtkFile = new ofstream();
83 VTK_FIELD_DRIVER(const string & fileName, FIELD<T> * ptrField)
84 : GENDRIVER(fileName,MED_EN::MED_WRONLY),
85 _ptrField((FIELD<T> *) ptrField),
86 _fieldName(fileName),_fieldNum(MED_INVALID)
88 const char * LOC = "VTK_FIELD_DRIVER::VTK_FIELD_DRIVER(const string & fileName, FIELD<T> * ptrField) ";
91 _vtkFile = new ofstream();
99 VTK_FIELD_DRIVER(const VTK_FIELD_DRIVER & fieldDriver):
100 GENDRIVER(fieldDriver),
101 _ptrField(fieldDriver._ptrField),
102 _fieldName(fieldDriver._fieldName),
103 _fieldNum(fieldDriver._fieldNum)
105 _ptrField->addDriver(*this);
106 _vtkFile = new ofstream();
114 const char * LOC ="VTK_FIELD_DRIVER::~VTK_FIELD_DRIVER()";
128 void openConst() const throw (MEDEXCEPTION)
130 const char * LOC = "VTK_FIELD_DRIVER::openConst()" ;
133 MESSAGE(LOC<<" : _fileName.c_str : "<< _fileName.c_str()<<",mode : "<< _accessMode);
135 if ( _fileName == "" )
136 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
137 << "_fileName is |\"\"|, please set a correct fileName before calling open()"
141 if (!(*_vtkFile).is_open())
142 (*_vtkFile).open(_fileName.c_str()) ;
144 // _status = MED_OPENED ;
148 SCRUTE((*_vtkFile).is_open());
154 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not open file "
160 void openConstAppend() const throw (MEDEXCEPTION)
162 const char * LOC = "VTK_FIELD_DRIVER::openConstAppend()" ;
165 MESSAGE(LOC<<" : _fileName.c_str : "<< _fileName.c_str()<<",mode : "<< _accessMode);
167 if ( _fileName == "" )
168 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
169 << "_fileName is |\"\"|, please set a correct fileName before calling open()"
173 SCRUTE((*_vtkFile).is_open());
175 if (!(*_vtkFile).is_open())
177 MESSAGE(LOC<<"The file is already close and it is opened with the right option");
178 (*_vtkFile).open(_fileName.c_str(), ofstream::out | ofstream::app) ;
182 MESSAGE(LOC<<"The file is still open, it is closed to make sure that it will be opened with the right option");
186 (*_vtkFile).close() ;
188 _vtkFile->open(_fileName.c_str(), ofstream::out | ofstream::app) ;
191 // _status = MED_OPENED ;
195 SCRUTE((*_vtkFile).is_open());
201 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not open file "
207 void open() throw (MEDEXCEPTION)
212 void openAppend() throw (MEDEXCEPTION)
217 void closeConst() const throw (MEDEXCEPTION)
219 const char * LOC = "VTK_FIELD_DRIVER::closeConst() " ;
226 if ((*_vtkFile).is_open())
230 // _status = MED_CLOSED ;
237 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not close file "
249 Set the name of the FIELD asked in file.
251 It could be different than the name of the FIELD object.
253 void setFieldName(const string & fieldName) ;
256 Get the name of the FIELD asked in file.
258 string getFieldName() const ;
261 Return a MEDEXCEPTION : it is the write-only driver.
263 void read ( void ) throw (MEDEXCEPTION) ;
266 Write FIELD in the specified file, with its mesh through its support
267 which has to be on all entities (excluding the faces in 3d and edges
270 void write( void ) const throw (MEDEXCEPTION) ;
273 Write FIELD in the specified file, the mesh is supposed to be
274 written in this file. The field support has to be on all entities
275 (excluding the faces in 3d and edges in 2d).
277 void writeAppend( void ) const throw (MEDEXCEPTION);
280 GENDRIVER * copy ( void ) const ;
284 /*-------------------------*/
285 /* template implementation */
286 /*-------------------------*/
288 /*--------------------- DRIVER PART -------------------------------*/
290 template <class T> void VTK_FIELD_DRIVER<T>::setFieldName(const string & fieldName)
292 _fieldName = fieldName;
295 template <class T> string VTK_FIELD_DRIVER<T>::getFieldName() const
300 template <class T> GENDRIVER * VTK_FIELD_DRIVER<T>::copy(void) const
302 VTK_FIELD_DRIVER<T> * myDriver = new VTK_FIELD_DRIVER<T>(*this);
307 template <class T> void VTK_FIELD_DRIVER<T>::read (void)
310 throw MEDEXCEPTION("VTK_FIELD_DRIVER::read : Can't read with a VTK driver because it is write only driver !");
313 template <class T> void VTK_FIELD_DRIVER<T>::write(void) const
316 const char * LOC = "VTK_FIELD_DRIVER::write(void) const " ;
319 // we get the Support and its associated Mesh
321 const SUPPORT * supportField = _ptrField->getSupport();
322 MESH * meshField = supportField->getMesh();
324 // Well we must open vtk file first, because there are
325 // no other driver than MED for VTK that do it !
328 // could we put more than one Mesh ?????
329 (*_vtkFile) << "# vtk DataFile Version 2.0" << endl
330 << "maillage from MedMemory" << endl ;
331 // only ASCII for the moment (binary came later :-)
332 (*_vtkFile) << "ASCII" << endl ;
334 (*_vtkFile) << "DATASET UNSTRUCTURED_GRID" << endl ;
335 // put points (all point are in 3D, so if we are in 1D or 2D, we complete by zero !
336 int SpaceDimension = meshField->getSpaceDimension() ;
337 int NumberOfNodes = meshField->getNumberOfNodes() ;
338 (*_vtkFile) << "POINTS " << NumberOfNodes << " float" << endl ;
339 const double *coordinate = meshField->getCoordinates(MED_EN::MED_FULL_INTERLACE) ;
340 for (int i=0;i<NumberOfNodes;i++) {
341 for (int j=0;j<SpaceDimension;j++)
342 (*_vtkFile) << coordinate[i*SpaceDimension+j] << " " ;
343 if (SpaceDimension==1)
344 (*_vtkFile) << "0 0" ;
345 if (SpaceDimension==2)
347 (*_vtkFile) << endl ;
350 // we put connectivity
351 // how many cells and how many value in connectivity :
352 int cells_types_count = meshField->getNumberOfTypes(MED_EN::MED_CELL) ;
353 // int * cells_count = meshField->get_cells_count() ;
354 // int cells_sum = cells_count[cells_types_count] ;
355 int cells_sum = meshField->getNumberOfElements(MED_EN::MED_CELL,MED_EN::MED_ALL_ELEMENTS) ;
356 const CELLMODEL * cells_type = meshField->getCellsTypes(MED_EN::MED_CELL) ;
357 // int connectivity_sum = 0 ;
359 //const int * connectivity = meshField->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,MED_CELL,MED_ALL_ELEMENTS) ; !! UNUSED VARIABLE !!
360 const int * connectivityIndex = meshField->getConnectivityIndex(MED_EN::MED_NODAL,MED_EN::MED_CELL) ;
362 int connectivity_sum = connectivityIndex[cells_sum]-1 ;
364 (*_vtkFile) << "CELLS " << cells_sum << " " << connectivity_sum+cells_sum << endl ;
365 // we put connectivity
366 for (int i=0;i<cells_types_count;i++) {
367 int *filter = (int*) NULL ; // index in vtk connectivity
368 switch (cells_type[i].getType())
370 case MED_EN::MED_POINT1 : {
371 filter = new int[1] ;
375 case MED_EN::MED_SEG2 : {
376 filter = new int[2] ;
381 case MED_EN::MED_SEG3 : {
384 case MED_EN::MED_TRIA3 : {
385 filter = new int[3] ;
391 case MED_EN::MED_QUAD4 : {
392 filter = new int[4] ;
399 case MED_EN::MED_TRIA6 : {
402 case MED_EN::MED_QUAD8 : {
405 case MED_EN::MED_TETRA4 : {
406 filter = new int[4] ;
409 filter[2] = 3 ; // 3td element in med are 4th in vtk (array begin at 0 !)
410 filter[3] = 2 ; // 4th element in med are 3rd in vtk (array begin at 0 !)
413 case MED_EN::MED_PYRA5 : {
414 filter = new int[5] ;
416 filter[1] = 3 ; // 2nd element in med are 4th in vtk (array begin at 0 !)
418 filter[3] = 1 ; // 4th element in med are 2nd in vtk (array begin at 0 !)
422 case MED_EN::MED_PENTA6 : {
423 filter = new int[6] ;
432 case MED_EN::MED_HEXA8 : {
433 filter = new int[8] ;
444 case MED_EN::MED_TETRA10 : {
447 case MED_EN::MED_PYRA13 : {
450 case MED_EN::MED_PENTA15 : {
453 case MED_EN::MED_HEXA20 : {
461 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": MED element type not supported yet : " << cells_type[i].getName() ) ) ;
462 int nodes_cell = cells_type[i].getNumberOfNodes();
463 int numberOfCell = meshField->getNumberOfElements(MED_EN::MED_CELL,cells_type[i].getType()) ;
464 const int * connectivityArray = meshField->getConnectivity(MED_EN::MED_FULL_INTERLACE,MED_EN::MED_NODAL,MED_EN::MED_CELL,cells_type[i].getType());
465 for (int j=0;j<numberOfCell;j++) {
466 (*_vtkFile) << nodes_cell << " " ;
467 for (int k=0;k<nodes_cell;k++)
468 (*_vtkFile) << connectivityArray[j*nodes_cell+filter[k]] - 1 << " " ;
469 (*_vtkFile) << endl ;
474 (*_vtkFile) << endl ;
476 (*_vtkFile) << "CELL_TYPES " << cells_sum << endl ;
477 for (int i=0;i<cells_types_count;i++) {
479 switch (cells_type[i].getType())
481 case MED_EN::MED_POINT1 : {
485 case MED_EN::MED_SEG2 : {
489 case MED_EN::MED_SEG3 : {
493 case MED_EN::MED_TRIA3 : {
497 case MED_EN::MED_QUAD4 : {
501 case MED_EN::MED_TRIA6 : {
505 case MED_EN::MED_QUAD8 : {
509 case MED_EN::MED_TETRA4 : {
513 case MED_EN::MED_PYRA5 : {
517 case MED_EN::MED_PENTA6 : {
521 case MED_EN::MED_HEXA8 : {
525 case MED_EN::MED_TETRA10 : {
529 case MED_EN::MED_PYRA13 : {
533 case MED_EN::MED_PENTA15 : {
537 case MED_EN::MED_HEXA20 : {
547 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": MED element type not supported yet : " << cells_type[i].getType() ) ) ;
548 int numberOfCell = meshField->getNumberOfElements(MED_EN::MED_CELL,cells_type[i].getType()) ;
549 for (int j=0;j<numberOfCell;j++)
550 (*_vtkFile) << vtkType << endl ;
553 // first : field on node
554 // fields is on all node !
556 // second : field on cell
557 // fields is on all cell !
559 int dt = _ptrField->getIterationNumber();
560 int it = _ptrField->getOrderNumber();
563 string nameField = _ptrField->getName();
564 MED_EN::medEntityMesh entitySupport = supportField->getEntity();
565 name << nameField << "_" << dt << "_" << it ;
567 if (!(supportField->isOnAllElements()))
568 throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<<_ptrField->getName()<<" which is not on all entities of the mesh !" << entitySupport));
570 if (entitySupport == MED_EN::MED_NODE)
571 (*_vtkFile) << "POINT_DATA " << meshField->getNumberOfNodes() << endl ;
572 else if (entitySupport == MED_EN::MED_CELL)
573 (*_vtkFile) << "CELL_DATA " << meshField->getNumberOfElements(MED_EN::MED_CELL,MED_EN::MED_ALL_ELEMENTS) << endl ;
575 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));
577 int NomberOfValue = supportField->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS) ;
578 int NomberOfComponents = _ptrField->getNumberOfComponents() ;
580 MED_EN::med_type_champ fieldType = _ptrField->getValueType() ;
587 case MED_EN::MED_INT32 :
591 case MED_EN::MED_REEL64 :
597 throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<< name.str() <<" the type is not int or double !"));
601 if (NomberOfComponents==3)
602 (*_vtkFile) << "VECTORS " << name.str() << " int" << endl ;
603 else if (NomberOfComponents<=4)
605 (*_vtkFile) << "SCALARS " << name.str() << " int " << NomberOfComponents << endl ;
606 (*_vtkFile) << "LOOKUP_TABLE default" << endl ;
609 throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<<_ptrField->getName()<<" there are more than 4 components !"));
611 const T * value = _ptrField->getValue(MED_EN::MED_NO_INTERLACE) ;
613 for (int i=0; i<NomberOfValue; i++)
615 for(int j=0; j<NomberOfComponents; j++)
616 (*_vtkFile) << value[j*NomberOfValue+i] << " " ;
617 (*_vtkFile) << endl ;
622 template <class T> void VTK_FIELD_DRIVER<T>::writeAppend(void) const
625 const char * LOC = "VTK_FIELD_DRIVER::writeAppend(void) const " ;
628 // we get the Support and its associated Mesh
630 const SUPPORT * supportField = _ptrField->getSupport();
631 MESH * meshField = supportField->getMesh();
633 // Well we must open vtk file first, because there are
634 // no other driver than MED for VTK that do it !
637 // first : field on node
638 // fields is on all node !
640 // second : field on cell
641 // fields is on all cell !
643 int dt = _ptrField->getIterationNumber();
644 int it = _ptrField->getOrderNumber();
647 string nameField = _ptrField->getName();
648 MED_EN::medEntityMesh entitySupport = supportField->getEntity();
649 name << nameField << "_" << dt << "_" << it ;
651 if (!(supportField->isOnAllElements()))
652 throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<<_ptrField->getName()<<" which is not on all entities of the mesh !" << entitySupport));
654 if (entitySupport == MED_EN::MED_NODE)
655 (*_vtkFile) << "POINT_DATA " << meshField->getNumberOfNodes() << endl ;
656 else if (entitySupport == MED_EN::MED_CELL)
657 (*_vtkFile) << "CELL_DATA " << meshField->getNumberOfElements(MED_EN::MED_CELL,MED_EN::MED_ALL_ELEMENTS) << endl ;
659 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));
661 int NomberOfValue = supportField->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS) ;
662 int NomberOfComponents = _ptrField->getNumberOfComponents() ;
664 MED_EN::med_type_champ fieldType = _ptrField->getValueType() ;
670 case MED_EN::MED_INT32 :
674 case MED_EN::MED_REEL64 :
680 throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<< name.str() <<" the type is not int or double !"));
684 if (NomberOfComponents==3)
685 (*_vtkFile) << "VECTORS " << name.str() << " int" << endl ;
686 else if (NomberOfComponents<=4)
688 (*_vtkFile) << "SCALARS " << name.str() << " int " << NomberOfComponents << endl ;
689 (*_vtkFile) << "LOOKUP_TABLE default" << endl ;
692 throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<<_ptrField->getName()<<" there are more than 4 components !"));
694 const T * value = _ptrField->getValue(MED_EN::MED_NO_INTERLACE) ;
696 for (int i=0; i<NomberOfValue; i++)
698 for(int j=0; j<NomberOfComponents; j++)
699 (*_vtkFile) << value[j*NomberOfValue+i] << " " ;
700 (*_vtkFile) << endl ;
704 }//End namespace MEDMEM
706 #endif /* VTK_FIELD_DRIVER_HXX */