1 // Copyright (C) 2007-2008 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
22 #ifndef VTK_FIELD_DRIVER_HXX
23 #define VTK_FIELD_DRIVER_HXX
29 #include "MEDMEM_define.hxx"
31 #include "MEDMEM_GenDriver.hxx"
32 #include "MEDMEM_Utilities.hxx"
34 #include "MEDMEM_STRING.hxx"
35 #include "MEDMEM_Exception.hxx"
36 #include "MEDMEM_Unit.hxx"
37 #include "MEDMEM_nArray.hxx"
38 #include "MEDMEM_ArrayConvert.hxx"
39 #include "MEDMEM_Support.hxx"
40 #include "MEDMEM_Mesh.hxx"
41 #include "MEDMEM_CellModel.hxx"
48 Generic part : implement open and close methods.
53 template <class T> class VTK_FIELD_DRIVER : public GENDRIVER
58 mutable ofstream * _vtkFile ;
64 // all MED cell type ?? Classe de Définition ??
65 // static const medGeometryElement all_cell_type[MED_NBR_GEOMETRIE_MAILLE];
67 // static const char * const all_cell_type_tab [MED_NBR_GEOMETRIE_MAILLE];
72 template <class INTERLACING_TAG>
73 VTK_FIELD_DRIVER():GENDRIVER(),
74 _ptrField((FIELD<T> *) 0), _fieldName(""),
75 _fieldNum(MED_INVALID)
77 const char * LOC = "VTK_FIELD_DRIVER::VTK_FIELD_DRIVER() ";
80 _vtkFile = new ofstream();
87 template <class INTERLACING_TAG>
88 VTK_FIELD_DRIVER(const string & fileName,
89 FIELD<T, INTERLACING_TAG> * ptrField):
90 GENDRIVER(fileName, MED_EN::WRONLY, VTK_DRIVER),
91 _ptrField((FIELD<T> *) ptrField),
92 _fieldName(fileName),_fieldNum(MED_INVALID)
94 const char* LOC = "VTK_FIELD_DRIVER::VTK_FIELD_DRIVER(const string & fileName, FIELD<T> * ptrField) ";
97 _vtkFile = new ofstream();
105 VTK_FIELD_DRIVER(const VTK_FIELD_DRIVER & fieldDriver):
106 GENDRIVER(fieldDriver),
107 _ptrField(fieldDriver._ptrField),
108 _fieldName(fieldDriver._fieldName),
109 _fieldNum(fieldDriver._fieldNum)
111 _ptrField->addDriver(*this);
112 _vtkFile = new ofstream();
120 const char* LOC = "VTK_FIELD_DRIVER::~VTK_FIELD_DRIVER()";
125 SCRUTE_MED(_vtkFile);
129 SCRUTE_MED(_vtkFile);
134 void openConst() const throw (MEDEXCEPTION)
136 const char * LOC = "VTK_FIELD_DRIVER::openConst()" ;
139 MESSAGE_MED(LOC<<" : _fileName.c_str : "<< _fileName.c_str()<<",mode : "<< _accessMode);
141 if ( _fileName == "" )
142 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
143 << "_fileName is |\"\"|, please set a correct fileName before calling open()"
147 if (!(*_vtkFile).is_open())
148 (*_vtkFile).open(_fileName.c_str()) ;
150 // _status = MED_OPENED ;
154 SCRUTE_MED((*_vtkFile).is_open());
155 SCRUTE_MED(_vtkFile);
160 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not open file "
166 void openConstAppend() const throw (MEDEXCEPTION)
168 const char * LOC = "VTK_FIELD_DRIVER::openConstAppend()" ;
171 MESSAGE_MED(LOC<<" : _fileName.c_str : "<< _fileName.c_str()<<",mode : "<< _accessMode);
173 if ( _fileName == "" )
174 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
175 << "_fileName is |\"\"|, please set a correct fileName before calling open()"
179 SCRUTE_MED((*_vtkFile).is_open());
181 if (!(*_vtkFile).is_open())
183 MESSAGE_MED(LOC<<"The file is already close and it is opened with the right option");
184 (*_vtkFile).open(_fileName.c_str(), ofstream::out | ofstream::app) ;
188 MESSAGE_MED(LOC<<"The file is still open, it is closed to make sure that it will be opened with the right option");
192 (*_vtkFile).close() ;
194 _vtkFile->open(_fileName.c_str(), ofstream::out | ofstream::app) ;
197 // _status = MED_OPENED ;
201 SCRUTE_MED((*_vtkFile).is_open());
202 SCRUTE_MED(_vtkFile);
207 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not open file "
213 void open() throw (MEDEXCEPTION)
218 void openAppend() throw (MEDEXCEPTION)
223 void closeConst() const throw (MEDEXCEPTION)
225 const char * LOC = "VTK_FIELD_DRIVER::closeConst() " ;
228 SCRUTE_MED(_vtkFile);
229 SCRUTE_MED(*_vtkFile);
232 if ((*_vtkFile).is_open())
236 // _status = MED_CLOSED ;
239 SCRUTE_MED(_vtkFile);
240 SCRUTE_MED(*_vtkFile);
242 if ( (*_vtkFile) && _vtkFile->is_open() )
244 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not close file "
256 Set the name of the FIELD asked in file.
258 It could be different than the name of the FIELD object.
260 void setFieldName(const string & fieldName) ;
263 Get the name of the FIELD asked in file.
265 string getFieldName() const ;
268 Return a MEDEXCEPTION : it is the write-only driver.
270 void read ( void ) throw (MEDEXCEPTION) ;
273 Write FIELD in the specified file, with its mesh through its support
274 which has to be on all entities (excluding the faces in 3d and edges
277 void write( void ) const throw (MEDEXCEPTION) ;
280 Write FIELD in the specified file, the mesh is supposed to be
281 written in this file. The field support has to be on all entities
282 (excluding the faces in 3d and edges in 2d).
284 void writeAppend( void ) const throw (MEDEXCEPTION);
287 GENDRIVER * copy ( void ) const ;
291 /*-------------------------*/
292 /* template implementation */
293 /*-------------------------*/
295 /*--------------------- DRIVER PART -------------------------------*/
297 template <class T> void VTK_FIELD_DRIVER<T>::setFieldName(const string & fieldName)
299 _fieldName = fieldName;
302 template <class T> string VTK_FIELD_DRIVER<T>::getFieldName() const
307 template <class T> GENDRIVER * VTK_FIELD_DRIVER<T>::copy(void) const
309 VTK_FIELD_DRIVER<T> * myDriver = new VTK_FIELD_DRIVER<T>(*this);
314 template <class T> void VTK_FIELD_DRIVER<T>::read (void)
317 throw MEDEXCEPTION("VTK_FIELD_DRIVER::read : Can't read with a VTK driver because it is write only driver !");
320 template <class T> void VTK_FIELD_DRIVER<T>::write(void) const
323 const char * LOC = "VTK_FIELD_DRIVER::write(void) const " ;
326 // we get the Support and its associated Mesh
328 const SUPPORT * supportField = _ptrField->getSupport();
329 MESH * meshField = supportField->getMesh();
331 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": mesh was not read before writing")) ;
333 // Well we must open vtk file first, because there are
334 // no other driver than MED for VTK that do it !
337 // could we put more than one Mesh ?????
338 (*_vtkFile) << "# vtk DataFile Version 2.0" << endl
339 << "maillage from MedMemory" << endl ;
340 // only ASCII for the moment (binary came later :-)
341 (*_vtkFile) << "ASCII" << endl ;
343 (*_vtkFile) << "DATASET UNSTRUCTURED_GRID" << endl ;
344 // put points (all point are in 3D, so if we are in 1D or 2D, we complete by zero !
345 int SpaceDimension = meshField->getSpaceDimension() ;
346 int NumberOfNodes = meshField->getNumberOfNodes() ;
347 (*_vtkFile) << "POINTS " << NumberOfNodes << " float" << endl ;
348 const double *coordinate = meshField->getCoordinates(MED_EN::MED_FULL_INTERLACE) ;
349 for (int i=0;i<NumberOfNodes;i++) {
350 for (int j=0;j<SpaceDimension;j++)
351 (*_vtkFile) << coordinate[i*SpaceDimension+j] << " " ;
352 if (SpaceDimension==1)
353 (*_vtkFile) << "0 0" ;
354 if (SpaceDimension==2)
356 (*_vtkFile) << endl ;
359 // we put connectivity
360 // how many cells and how many value in connectivity :
361 int cells_types_count = meshField->getNumberOfTypes(MED_EN::MED_CELL) ;
362 // int * cells_count = meshField->get_cells_count() ;
363 // int cells_sum = cells_count[cells_types_count] ;
364 int cells_sum = meshField->getNumberOfElements(MED_EN::MED_CELL,MED_EN::MED_ALL_ELEMENTS) ;
365 const CELLMODEL * cells_type = meshField->getCellsTypes(MED_EN::MED_CELL) ;
366 // int connectivity_sum = 0 ;
368 //const int * connectivity = meshField->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,MED_CELL,MED_ALL_ELEMENTS) ; !! UNUSED VARIABLE !!
369 const int * connectivityIndex = meshField->getConnectivityIndex(MED_EN::MED_NODAL,MED_EN::MED_CELL) ;
371 int connectivity_sum = connectivityIndex[cells_sum]-1 ;
373 (*_vtkFile) << "CELLS " << cells_sum << " " << connectivity_sum+cells_sum << endl ;
374 // we put connectivity
375 for (int i=0;i<cells_types_count;i++) {
376 int *filter = (int*) NULL ; // index in vtk connectivity
377 switch (cells_type[i].getType())
379 case MED_EN::MED_POINT1 : {
380 filter = new int[1] ;
384 case MED_EN::MED_SEG2 : {
385 filter = new int[2] ;
390 case MED_EN::MED_SEG3 : {
393 case MED_EN::MED_TRIA3 : {
394 filter = new int[3] ;
400 case MED_EN::MED_QUAD4 : {
401 filter = new int[4] ;
408 case MED_EN::MED_TRIA6 : {
411 case MED_EN::MED_QUAD8 : {
414 case MED_EN::MED_TETRA4 : {
415 filter = new int[4] ;
418 filter[2] = 3 ; // 3td element in med are 4th in vtk (array begin at 0 !)
419 filter[3] = 2 ; // 4th element in med are 3rd in vtk (array begin at 0 !)
422 case MED_EN::MED_PYRA5 : {
423 filter = new int[5] ;
425 filter[1] = 3 ; // 2nd element in med are 4th in vtk (array begin at 0 !)
427 filter[3] = 1 ; // 4th element in med are 2nd in vtk (array begin at 0 !)
431 case MED_EN::MED_PENTA6 : {
432 filter = new int[6] ;
441 case MED_EN::MED_HEXA8 : {
442 filter = new int[8] ;
453 case MED_EN::MED_TETRA10 : {
456 case MED_EN::MED_PYRA13 : {
459 case MED_EN::MED_PENTA15 : {
462 case MED_EN::MED_HEXA20 : {
470 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": MED element type not supported yet : " << cells_type[i].getName() ) ) ;
471 int nodes_cell = cells_type[i].getNumberOfNodes();
472 int numberOfCell = meshField->getNumberOfElements(MED_EN::MED_CELL,cells_type[i].getType()) ;
473 const int * connectivityArray = meshField->getConnectivity(MED_EN::MED_FULL_INTERLACE,MED_EN::MED_NODAL,MED_EN::MED_CELL,cells_type[i].getType());
474 for (int j=0;j<numberOfCell;j++) {
475 (*_vtkFile) << nodes_cell << " " ;
476 for (int k=0;k<nodes_cell;k++)
477 (*_vtkFile) << connectivityArray[j*nodes_cell+filter[k]] - 1 << " " ;
478 (*_vtkFile) << endl ;
483 (*_vtkFile) << endl ;
485 (*_vtkFile) << "CELL_TYPES " << cells_sum << endl ;
486 for (int i=0;i<cells_types_count;i++) {
488 switch (cells_type[i].getType())
490 case MED_EN::MED_POINT1 : {
494 case MED_EN::MED_SEG2 : {
498 case MED_EN::MED_SEG3 : {
502 case MED_EN::MED_TRIA3 : {
506 case MED_EN::MED_QUAD4 : {
510 case MED_EN::MED_TRIA6 : {
514 case MED_EN::MED_QUAD8 : {
518 case MED_EN::MED_TETRA4 : {
522 case MED_EN::MED_PYRA5 : {
526 case MED_EN::MED_PENTA6 : {
530 case MED_EN::MED_HEXA8 : {
534 case MED_EN::MED_TETRA10 : {
538 case MED_EN::MED_PYRA13 : {
542 case MED_EN::MED_PENTA15 : {
546 case MED_EN::MED_HEXA20 : {
556 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": MED element type not supported yet : " << cells_type[i].getType() ) ) ;
557 int numberOfCell = meshField->getNumberOfElements(MED_EN::MED_CELL,cells_type[i].getType()) ;
558 for (int j=0;j<numberOfCell;j++)
559 (*_vtkFile) << vtkType << endl ;
562 // first : field on node
563 // fields is on all node !
565 // second : field on cell
566 // fields is on all cell !
568 int dt = _ptrField->getIterationNumber();
569 int it = _ptrField->getOrderNumber();
572 string nameField = _ptrField->getName();
573 MED_EN::medEntityMesh entitySupport = supportField->getEntity();
574 name << nameField << "_" << dt << "_" << it ;
576 if ( _ptrField->getGaussPresence() )
577 throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<<_ptrField->getName()<<" which use Gauss Points !" << entitySupport));
579 if (!(supportField->isOnAllElements()))
580 throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<<_ptrField->getName()<<" which is not on all entities of the mesh !" << entitySupport));
582 if (entitySupport == MED_EN::MED_NODE)
583 (*_vtkFile) << "POINT_DATA " << meshField->getNumberOfNodes() << endl ;
584 else if (entitySupport == MED_EN::MED_CELL)
585 (*_vtkFile) << "CELL_DATA " << meshField->getNumberOfElements(MED_EN::MED_CELL,MED_EN::MED_ALL_ELEMENTS) << endl ;
587 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));
589 int NomberOfValue = supportField->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS) ;
590 int NomberOfComponents = _ptrField->getNumberOfComponents() ;
592 MED_EN::med_type_champ fieldType = _ptrField->getValueType() ;
594 SCRUTE_MED(name.str());
595 SCRUTE_MED(fieldType);
599 case MED_EN::MED_INT32 :
603 case MED_EN::MED_REEL64 :
609 throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<< name.str() <<" the type is not int or double !"));
613 if (NomberOfComponents==3)
614 (*_vtkFile) << "VECTORS " << name.str() << " int" << endl ;
615 else if (NomberOfComponents<=4)
617 (*_vtkFile) << "SCALARS " << name.str() << " int " << NomberOfComponents << endl ;
618 (*_vtkFile) << "LOOKUP_TABLE default" << endl ;
621 throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<<_ptrField->getName()<<" there are more than 4 components !"));
623 // IL EST POSSIBLE D'AVOIR LES DEUX BOUCLES D'ECRITURE POUR EVITER
624 // DE CONVERTIR LE CHAMP DANS LE BON TYPE D'ENTRELACEMENT
626 MEDMEM_Array_ * tmpArray = 0;
627 if ( _ptrField->getInterlacingType() == MED_EN::MED_NO_INTERLACE )
628 value = _ptrField->getValue();
629 else if ( _ptrField->getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ) {
630 MEDMEM_Array_ * ptrArray = _ptrField->getArray();
631 MEDMEM_Array<T,NoInterlaceByTypeNoGaussPolicy> * temp = dynamic_cast<MEDMEM_Array<T,NoInterlaceByTypeNoGaussPolicy> * > ( ptrArray );
632 MEDMEM_Array<T,NoInterlaceNoGaussPolicy> * array = ArrayConvert2No( *temp );
634 value = array->getPtr();
637 MEDMEM_Array_ * ptrArray = _ptrField->getArray();
638 MEDMEM_Array<T,FullInterlaceNoGaussPolicy> * temp = dynamic_cast<MEDMEM_Array<T,FullInterlaceNoGaussPolicy> * > ( ptrArray );
639 MEDMEM_Array<T,NoInterlaceNoGaussPolicy> * array = ArrayConvert( *temp );
641 value = array->getPtr();
644 for (int i=0; i<NomberOfValue; i++)
646 for(int j=0; j<NomberOfComponents; j++)
647 (*_vtkFile) << value[j*NomberOfValue+i] << " " ;
648 (*_vtkFile) << endl ;
651 if ( _ptrField->getInterlacingType() != MED_EN::MED_NO_INTERLACE )
656 template <class T> void VTK_FIELD_DRIVER<T>::writeAppend(void) const
659 const char * LOC = "VTK_FIELD_DRIVER::writeAppend(void) const " ;
662 // we get the Support and its associated Mesh
664 const SUPPORT * supportField = _ptrField->getSupport();
665 MESH * meshField = supportField->getMesh();
667 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": mesh was not read before writing")) ;
669 // Well we must open vtk file first, because there are
670 // no other driver than MED for VTK that do it !
673 // first : field on node
674 // fields is on all node !
676 // second : field on cell
677 // fields is on all cell !
679 int dt = _ptrField->getIterationNumber();
680 int it = _ptrField->getOrderNumber();
683 string nameField = _ptrField->getName();
684 MED_EN::medEntityMesh entitySupport = supportField->getEntity();
685 name << nameField << "_" << dt << "_" << it ;
687 if ( _ptrField->getGaussPresence() )
688 throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<<_ptrField->getName()<<" which use Gauss Points !" << entitySupport));
690 if (!(supportField->isOnAllElements()))
691 throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<<_ptrField->getName()<<" which is not on all entities of the mesh !" << entitySupport));
693 if (entitySupport == MED_EN::MED_NODE)
694 (*_vtkFile) << "POINT_DATA " << meshField->getNumberOfNodes() << endl ;
695 else if (entitySupport == MED_EN::MED_CELL)
696 (*_vtkFile) << "CELL_DATA " << meshField->getNumberOfElements(MED_EN::MED_CELL,MED_EN::MED_ALL_ELEMENTS) << endl ;
698 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));
700 int NomberOfValue = supportField->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS) ;
701 int NomberOfComponents = _ptrField->getNumberOfComponents() ;
703 MED_EN::med_type_champ fieldType = _ptrField->getValueType() ;
705 SCRUTE_MED(name.str());
706 SCRUTE_MED(fieldType);
709 case MED_EN::MED_INT32 :
713 case MED_EN::MED_REEL64 :
719 throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<< name.str() <<" the type is not int or double !"));
723 if (NomberOfComponents==3)
724 (*_vtkFile) << "VECTORS " << name.str() << " int" << endl ;
725 else if (NomberOfComponents<=4)
727 (*_vtkFile) << "SCALARS " << name.str() << " int " << NomberOfComponents << endl ;
728 (*_vtkFile) << "LOOKUP_TABLE default" << endl ;
731 throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<<_ptrField->getName()<<" there are more than 4 components !"));
734 MEDMEM_Array_ * tmpArray = 0;
735 if ( _ptrField->getInterlacingType() == MED_EN::MED_NO_INTERLACE )
736 value = _ptrField->getValue();
737 else if ( _ptrField->getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ) {
738 MEDMEM_Array_ * ptrArray = _ptrField->getArray();
739 MEDMEM_Array<T,NoInterlaceByTypeNoGaussPolicy> * temp = dynamic_cast<MEDMEM_Array<T,NoInterlaceByTypeNoGaussPolicy> * > ( ptrArray );
740 MEDMEM_Array<T,NoInterlaceNoGaussPolicy> * array = ArrayConvert2No( *temp );
742 value = array->getPtr();
745 MEDMEM_Array_ * ptrArray = _ptrField->getArray();
746 MEDMEM_Array<T,FullInterlaceNoGaussPolicy> * temp = dynamic_cast<MEDMEM_Array<T,FullInterlaceNoGaussPolicy> * > ( ptrArray );
747 MEDMEM_Array<T,NoInterlaceNoGaussPolicy> * array = ArrayConvert( *temp );
749 value = array->getPtr();
752 for (int i=0; i<NomberOfValue; i++)
754 for(int j=0; j<NomberOfComponents; j++)
755 (*_vtkFile) << value[j*NomberOfValue+i] << " " ;
756 (*_vtkFile) << endl ;
759 if ( _ptrField->getInterlacingType() != MED_EN::MED_NO_INTERLACE )
764 }//End namespace MEDMEM
766 #endif /* VTK_FIELD_DRIVER_HXX */