Back to index

salome-med  6.5.0
MEDMEM_VtkMeshDriver.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 #include "MEDMEM_VtkMeshDriver.hxx"
00024 
00025 #include "MEDMEM_DriversDef.hxx"
00026 
00027 #include "MEDMEM_CellModel.hxx"
00028 #include "MEDMEM_Connectivity.hxx"
00029 #include "MEDMEM_Coordinate.hxx"
00030 #include "MEDMEM_DriverFactory.hxx"
00031 #include "MEDMEM_Family.hxx"
00032 #include "MEDMEM_Grid.hxx"
00033 #include "MEDMEM_Group.hxx"
00034 #include "MEDMEM_Mesh.hxx"
00035 
00036 #include <fcntl.h>
00037 #include <sstream>
00038 
00039 using namespace std;
00040 using namespace MEDMEM;
00041 using namespace MED_EN;
00042 
00043 VTK_MESH_DRIVER::VTK_MESH_DRIVER(): GENDRIVER(VTK_DRIVER), 
00044                                     _ptrMesh((MESH * const)MED_NULL)
00045 {
00046   //_vtkFile = new ofstream();
00047   _vtkFile = 0;
00048   _binaryFile = 0;
00049   // What about _id in Gendriver ?
00050   // _driverType ???
00051 }
00052 
00053 VTK_MESH_DRIVER::VTK_MESH_DRIVER(const string & fileName, const GMESH *  ptrMesh) :
00054   GENDRIVER(fileName, WRONLY, VTK_DRIVER),
00055   _ptrMesh(ptrMesh)
00056 {
00057 
00058   // Send an exception because a VTK_MESH_DRIVER object cannot be instantied
00059   // from a file and there is no read for that kind of driver
00060 
00061   //  throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "This driver is only used to write in VTK format So thie object can not be instantied using a file!"));
00062 
00063   //  _ptrMesh->addDriver(*this); // OU RECUPERER L'ID.
00064   MESSAGE_MED("VTK_MESH_DRIVER::VTK_MESH_DRIVER(const string & fileName, MESH * ptrMesh) : "
00065           << "WARNING this driver is only used to write in VTK format So the object can not be instantied using a file!");
00066 
00067   //_vtkFile = new ofstream();
00068   _vtkFile = 0;
00069   _binaryFile = 0;
00070 }
00071 
00072 VTK_MESH_DRIVER::VTK_MESH_DRIVER(const VTK_MESH_DRIVER & driver): 
00073   GENDRIVER(driver),
00074   _ptrMesh(driver._ptrMesh),
00075   _meshName(driver._meshName)
00076 {
00077   // next string commented by skl for bug NPAL14840
00078   //_ptrMesh->addDriver(*this);
00079   //_vtkFile = new ofstream();
00080   _vtkFile = 0;
00081   _binaryFile = 0;
00082 }
00083 
00084 VTK_MESH_DRIVER::~VTK_MESH_DRIVER()
00085 {
00086   const char* LOC = "VTK_MESH_DRIVER::~VTK_MESH_DRIVER()";
00087   BEGIN_OF_MED(LOC);
00088 
00089   close();
00090 
00091   SCRUTE_MED(_vtkFile);
00092 
00093   if ( _vtkFile )
00094     delete _vtkFile ;
00095   if ( _binaryFile )
00096     delete _binaryFile;
00097 
00098   _vtkFile = 0;
00099   _binaryFile = 0;
00100 
00101   SCRUTE_MED(_vtkFile);
00102 
00103   END_OF_MED(LOC);
00104 }
00105 
00106 void VTK_MESH_DRIVER::openConst() const throw (MEDEXCEPTION)
00107 {
00108   const char * LOC = "VTK_MESH_DRIVER::openConst() " ;
00109   BEGIN_OF_MED(LOC);
00110 
00111   MESSAGE_MED(LOC<<" : _fileName.c_str : "<< _fileName.c_str()<<",mode : "<< _accessMode);
00112 
00113   if ( _fileName == "" )
00114     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
00115                                      << "_fileName is |\"\"|, please set a correct fileName before calling open()"));
00116 
00117   if ( DRIVERFACTORY::getVtkBinaryFormatForWriting() )
00118     {
00119       if ( _vtkFile )
00120         {
00121           closeConst();
00122           delete _vtkFile;
00123           _vtkFile = 0;
00124         }
00125       if ( !_binaryFile )
00126         {
00127           _binaryFile = new _VTK_BinaryWriter( _fileName );
00128           if (!_binaryFile->open())
00129             {
00130               delete _binaryFile;
00131               _binaryFile = 0;
00132               throw MED_EXCEPTION( LOCALIZED( STRING(LOC) << "Could not open file "<< _fileName));
00133             }
00134         }
00135     }
00136   else
00137     {
00138       if ( _binaryFile )
00139         {
00140           closeConst();
00141           delete _binaryFile;
00142           _binaryFile = 0;
00143         }
00144  
00145       if (!_vtkFile )
00146         _vtkFile = new ofstream();
00147       if (!(*_vtkFile).is_open())
00148         (*_vtkFile).open(_fileName.c_str()) ; 
00149 
00150       if (!(*_vtkFile))
00151         {
00152           delete _vtkFile;
00153           _vtkFile = 0;
00154           throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not open file "<< _fileName));
00155         }
00156     }
00157   END_OF_MED(LOC);
00158 }
00159 
00160 void VTK_MESH_DRIVER::open() {
00161   openConst() ;
00162 }
00163 
00164 void VTK_MESH_DRIVER::closeConst() const throw (MEDEXCEPTION)
00165 {
00166   const char * LOC = "VTK_MESH_DRIVER::closeConst() " ;
00167   BEGIN_OF_MED(LOC);
00168 
00169   if ( _vtkFile )
00170     {
00171       if ((*_vtkFile).is_open())
00172         (*_vtkFile).close();
00173   
00174       if ( (*_vtkFile) && _vtkFile->is_open() )
00175         throw MED_EXCEPTION( LOCALIZED( STRING(LOC) << "Could not close file "<< _fileName));
00176     }
00177   if ( _binaryFile )
00178     {
00179       _binaryFile->close();
00180       delete _binaryFile;
00181       ((VTK_MESH_DRIVER*)this)->_binaryFile = 0;
00182     }
00183   END_OF_MED(LOC);
00184 }
00185 
00186 void VTK_MESH_DRIVER::close() {
00187   closeConst() ;
00188 }
00189 
00190 void    VTK_MESH_DRIVER::setMeshName(const string & meshName) { _meshName = meshName; }
00191 string  VTK_MESH_DRIVER::getMeshName() const { return _meshName; }
00192 
00193 void VTK_MESH_DRIVER::read(void) throw (MEDEXCEPTION)
00194 {
00195   const char * LOC = "VTK_MESH_DRIVER::read() : " ;
00196   BEGIN_OF_MED(LOC);
00197 
00198   // Send an exception
00199 
00200   throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "This driver is only used to write in VTK format !"));
00201 
00202   END_OF_MED(LOC);
00203 }
00204 
00205 
00206 void VTK_MESH_DRIVER::write(void) const
00207   throw (MEDEXCEPTION)
00208 {
00209   const char * LOC = "void VTK_MESH_DRIVER::write(void) const : ";
00210   BEGIN_OF_MED(LOC);
00211 
00212   if ( !_ptrMesh )
00213     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Mesh is NULL"));
00214 
00215   // Well we must open vtk file first, because there are
00216   // no other driver than MED for VTK that do it !
00217 
00218   int SpaceDimension = _ptrMesh->getSpaceDimension() ;
00219   int NumberOfNodes  = _ptrMesh->getNumberOfNodes() ;
00220   if ( SpaceDimension < 1 )
00221     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Mesh is empty"));
00222 
00223   openConst();
00224 
00225   const MESH* mesh = _ptrMesh->convertInMESH();
00226   char buf[256];
00227   const char* header = "# vtk DataFile Version 2.0\n";
00228   const char* title  = "maillage from MedMemory\n";
00229   const char* dataset = "DATASET UNSTRUCTURED_GRID\n";
00230   if ( _vtkFile ) // ASCII
00231     {
00232       (*_vtkFile) << header ;
00233       (*_vtkFile) << title ;
00234       (*_vtkFile) << "ASCII" << endl ;
00235       (*_vtkFile) << dataset ;
00236       // put points (all point are in 3D, so if we are in 1D or 2D, we complete by zero !
00237       (*_vtkFile) << "POINTS " << NumberOfNodes << " float" << endl ;
00238       const double *coordinate = mesh->getCoordinates(MED_FULL_INTERLACE) ;
00239       string missingCoord = SpaceDimension==3 ? "" : SpaceDimension==2 ? "0" : "0 0";
00240       for (int i=0;i<NumberOfNodes;i++)
00241         {
00242           for (int j=0;j<SpaceDimension;j++)
00243             (*_vtkFile) << coordinate[i*SpaceDimension+j] << " ";
00244           (*_vtkFile) << missingCoord << endl;
00245         }
00246     }
00247   else // BINARY
00248     {
00249       const char* format = "BINARY\n";
00250       writeBinary( header,  strlen(header) );
00251       writeBinary( title,   strlen(title) );
00252       writeBinary( format,  strlen(format) );
00253       writeBinary( dataset, strlen(dataset) );
00254 
00255       // put points (all point are in 3D, so if we are in 1D or 2D, we complete by zero !
00256       //sprintf(buf,"POINTS %d double\n", NumberOfNodes);
00257       sprintf(buf,"POINTS %d float\n", NumberOfNodes);
00258       writeBinary( buf, strlen(buf) );
00259       const double *coordinate = mesh->getCoordinates(MED_FULL_INTERLACE) ;
00260       //PointerOf<double> coordBuf( SpaceDimension==3 ? 0 : NumberOfNodes * 3 );
00261       //double * toCoord = coordBuf;
00262       PointerOf<float> coordBuf( NumberOfNodes * 3 );
00263       float * toCoord = coordBuf;
00264       switch( SpaceDimension )
00265         {
00266         case 3:
00267           for (int i=0;i<NumberOfNodes;i++)
00268             {
00269               *toCoord++ = (float)*coordinate++;
00270               *toCoord++ = (float)*coordinate++;
00271               *toCoord++ = (float)*coordinate++;
00272             }
00273           break;
00274         case 2:
00275           for (int i=0;i<NumberOfNodes;i++)
00276             {
00277               *toCoord++ = (float)*coordinate++;
00278               *toCoord++ = (float)*coordinate++;
00279               *toCoord++ = 0;
00280             }
00281           break;
00282         case 1:
00283           for (int i=0;i<NumberOfNodes;i++)
00284             {
00285               *toCoord++ = (float)*coordinate++;
00286               *toCoord++ = 0;
00287               *toCoord++ = 0;
00288             }
00289           break;
00290 //           coordBuf.set( coordinate );
00291 //           break;
00292 //         case 2:
00293 //           for (int i=0;i<NumberOfNodes;i++)
00294 //             {
00295 //               *toCoord++ = *coordinate++;
00296 //               *toCoord++ = *coordinate++;
00297 //               *toCoord++ = 0;
00298 //             }
00299 //           break;
00300 //         case 1:
00301 //           for (int i=0;i<NumberOfNodes;i++)
00302 //             {
00303 //               *toCoord++ = *coordinate++;
00304 //               *toCoord++ = 0;
00305 //               *toCoord++ = 0;
00306 //             }
00307 //           break;
00308         }
00309       //writeBinary( (double*) coordBuf, NumberOfNodes * 3 );
00310       writeBinary( (float*) coordBuf, NumberOfNodes * 3 );
00311     }
00312 
00313   // we put connectivity
00314   // how many cells and how many value in connectivity :
00315   int cells_types_count        = mesh->getNumberOfTypes(MED_CELL) ;
00316   int cells_sum                = mesh->getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) ;
00317   const CELLMODEL * cells_type = mesh->getCellsTypes(MED_CELL) ;
00318 
00319   const int * connectivityIndex = mesh->getConnectivityIndex(MED_NODAL,MED_CELL) ;
00320   int          connectivity_sum =  connectivityIndex[cells_sum]-1 ;
00321 
00322   sprintf(buf,"\nCELLS %d %d\n", cells_sum, connectivity_sum+cells_sum);
00323   if ( _vtkFile )
00324     (*_vtkFile) << buf ;
00325   else
00326     writeBinary( buf, strlen(buf) );
00327 
00328   for (int i=0;i<cells_types_count;i++) {
00329     int *filter = (int*) NULL ; // index in vtk connectivity
00330     switch (cells_type[i].getType())
00331       {
00332       case MED_POINT1  : {
00333         filter = new int[1] ;
00334         filter[0] = 0 ;
00335         break ;
00336       }
00337       case MED_SEG2    : {
00338         filter = new int[2] ;
00339         filter[0] = 0 ;
00340         filter[1] = 1 ;
00341         break ;
00342       }
00343       case MED_SEG3    : {  
00344         break ;
00345       }
00346       case MED_TRIA3   : {
00347         filter = new int[3] ;
00348         filter[0] = 0 ;
00349         filter[1] = 1 ;
00350         filter[2] = 2 ;
00351         break ;
00352       }
00353       case MED_QUAD4   : {
00354         filter = new int[4] ;
00355         filter[0] = 0 ;
00356         filter[1] = 1 ;
00357         filter[2] = 2 ;
00358         filter[3] = 3 ;
00359         break ;
00360       }
00361       case MED_TRIA6   : {
00362         break ;
00363       }
00364       case MED_QUAD8   : {
00365         break ;
00366       }
00367       case MED_TETRA4  : {
00368         filter = new int[4] ;
00369         filter[0] = 0 ;
00370         filter[1] = 1 ;
00371         filter[2] = 3 ;  // 3td element in med are 4th in vtk (array begin at 0 !)
00372         filter[3] = 2 ;  // 4th element in med are 3rd in vtk (array begin at 0 !)
00373         break ;
00374       }
00375       case MED_PYRA5   : {
00376         filter = new int[5] ;
00377         filter[0] = 0 ;
00378         filter[1] = 3 ;  // 2nd element in med are 4th in vtk (array begin at 0 !)
00379         filter[2] = 2 ;
00380         filter[3] = 1 ;  // 4th element in med are 2nd in vtk (array begin at 0 !)
00381         filter[4] = 4 ;
00382         break ;
00383       }
00384       case MED_PENTA6  : {
00385         filter = new int[6] ;
00386         filter[0] = 0 ;
00387         filter[1] = 1 ;
00388         filter[2] = 2 ;
00389         filter[3] = 3 ;
00390         filter[4] = 4 ;
00391         filter[5] = 5 ;
00392         break ;
00393       }
00394       case MED_HEXA8   : {
00395         filter = new int[8] ;
00396         filter[0] = 0 ;
00397         filter[1] = 3 ;
00398         filter[2] = 2 ;
00399         filter[3] = 1 ;
00400         filter[4] = 4 ;
00401         filter[5] = 7 ;
00402         filter[6] = 6 ;
00403         filter[7] = 5 ;
00404         break ;
00405       }
00406       case MED_TETRA10 : {
00407         break ;
00408       }
00409       case MED_PYRA13  : {
00410         break ;
00411       }
00412       case MED_PENTA15 : {
00413         break ;
00414       }
00415       case MED_HEXA20  : {
00416         break ;
00417       }
00418       default : { 
00419         break ;
00420       }
00421       }
00422     if (filter==NULL) 
00423       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": MED element type not supported yet : " << cells_type[i].getName() ) ) ;
00424     int nodes_cell = cells_type[i].getNumberOfNodes();
00425     int numberOfCell = mesh->getNumberOfElements(MED_CELL,cells_type[i].getType()) ;
00426     const int * connectivityArray = mesh->getConnectivity(MED_NODAL,MED_CELL,cells_type[i].getType());
00427     if ( _vtkFile )
00428       {
00429         for (int j=0;j<numberOfCell;j++)
00430           {
00431             (*_vtkFile) << nodes_cell << " " ;
00432             for (int k=0;k<nodes_cell;k++)
00433               (*_vtkFile) << connectivityArray[j*nodes_cell+filter[k]] - 1 << " " ;
00434             (*_vtkFile) << endl ;
00435           }
00436       }
00437     else // BINARY
00438       {
00439         int dataSize = numberOfCell * ( nodes_cell+1 );
00440         PointerOf<int> cellData( dataSize );
00441         for (int *pCellData = cellData, j = 0; j < numberOfCell; j++)
00442           {
00443             *pCellData++ = nodes_cell;
00444             for (int k=0;k<nodes_cell;k++)
00445               *pCellData++ = connectivityArray[j*nodes_cell+filter[k]] - 1;
00446           }
00447         writeBinary( (int*) cellData, dataSize );
00448       }
00449     if (filter != NULL)
00450       delete[] filter ;
00451   }
00452   sprintf(buf,"\nCELL_TYPES %d\n", cells_sum);
00453   if ( _vtkFile )
00454     (*_vtkFile) << buf ;
00455   else
00456     writeBinary( buf, strlen(buf) );
00457 
00458   for (int i=0;i<cells_types_count;i++) {
00459     int vtkType = 0 ;
00460     switch (cells_type[i].getType())
00461       {
00462       case MED_POINT1  :vtkType = 1 ;break ;
00463       case MED_SEG2    :vtkType = 3 ;break ;
00464       case MED_SEG3    :vtkType = 0 ;break ;
00465       case MED_TRIA3   :vtkType = 5 ;break ;
00466       case MED_QUAD4   :vtkType = 9 ;break ;
00467       case MED_TRIA6   :vtkType = 0 ;break ;
00468       case MED_QUAD8   :vtkType = 0 ;break ;
00469       case MED_TETRA4  :vtkType = 10 ;break ;
00470       case MED_PYRA5   :vtkType = 14 ;break ;
00471       case MED_PENTA6  :vtkType = 13 ;break ;
00472       case MED_HEXA8   :vtkType = 12 ;break ;
00473       case MED_TETRA10 :vtkType = 0 ;break ;
00474       case MED_PYRA13  :vtkType = 0 ;break ;
00475       case MED_PENTA15 :vtkType = 0 ;break ;
00476       case MED_HEXA20  :vtkType = 0 ;break ;
00477       default          :vtkType = 0 ;break ;
00478       }
00479     if (vtkType == 0)
00480       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": MED element type not supported yet : " << cells_type[i].getType() ) ) ;
00481     int numberOfCell = mesh->getNumberOfElements(MED_CELL,cells_type[i].getType()) ;
00482     if ( _vtkFile )
00483       {
00484         for (int j=0;j<numberOfCell;j++)
00485           (*_vtkFile) << vtkType << endl ;
00486       }
00487     else
00488       {
00489         vector< int > type( numberOfCell, vtkType );
00490         writeBinary( &type[0], type.size() );
00491       }
00492   }
00493   mesh->removeReference();
00494 
00495   closeConst();
00496 
00497   END_OF_MED(LOC);
00498 } 
00499 
00500 GENDRIVER * VTK_MESH_DRIVER::copy(void) const
00501 {
00502   return new VTK_MESH_DRIVER(*this);
00503 }
00504 
00506 // _VTK_BinaryWriter
00508 
00509 _VTK_BinaryWriter::_VTK_BinaryWriter(const std::string file):_fileName(file),_binaryFile(0)
00510 {
00511 }
00512 
00513 bool _VTK_BinaryWriter::open(bool append) const
00514 {
00515   if ( !_binaryFile )
00516     {
00517       // workaround to create file with good access rights
00518       if ( !append )
00519         fstream(_fileName.c_str(), ios_base::out);
00520 
00521       // opening
00522       _VTK_BinaryWriter* mutableMe =(_VTK_BinaryWriter*) this;
00523       int append_flag = 0;
00524 #ifdef WNT
00525       if ( append ) append_flag = _O_APPEND;
00526       mutableMe->_binaryFile = ::_open (_fileName.c_str(), _O_WRONLY|_O_BINARY|append_flag);
00527 #else
00528       if ( append ) append_flag = O_APPEND;
00529       mutableMe->_binaryFile = ::open (_fileName.c_str(), O_WRONLY|append_flag);
00530 #endif
00531       if (_binaryFile < 0)
00532         mutableMe->_binaryFile = 0;
00533     }
00534   return _binaryFile;
00535 }
00536 
00537 bool _VTK_BinaryWriter::close() const
00538 {
00539   if ( _binaryFile )
00540     {
00541 #ifdef WNT
00542       ::_close (_binaryFile);
00543 #else
00544       ::close (_binaryFile);
00545 #endif
00546       ((_VTK_BinaryWriter*)this)->_binaryFile = 0;
00547     }
00548   return true;
00549 }