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 #include "MEDMEM_VtkMeshDriver.hxx"
25 #include "MEDMEM_DriversDef.hxx"
27 #include "MEDMEM_CellModel.hxx"
28 #include "MEDMEM_Connectivity.hxx"
29 #include "MEDMEM_Coordinate.hxx"
30 #include "MEDMEM_DriverFactory.hxx"
31 #include "MEDMEM_Family.hxx"
32 #include "MEDMEM_Grid.hxx"
33 #include "MEDMEM_Group.hxx"
34 #include "MEDMEM_Mesh.hxx"
40 using namespace MEDMEM;
41 using namespace MED_EN;
43 VTK_MESH_DRIVER::VTK_MESH_DRIVER(): GENDRIVER(VTK_DRIVER),
44 _ptrMesh((MESH * const)MED_NULL)
46 //_vtkFile = new ofstream();
49 // What about _id in Gendriver ?
53 VTK_MESH_DRIVER::VTK_MESH_DRIVER(const string & fileName, const GMESH * ptrMesh) :
54 GENDRIVER(fileName, WRONLY, VTK_DRIVER),
58 // Send an exception because a VTK_MESH_DRIVER object cannot be instantied
59 // from a file and there is no read for that kind of driver
61 // 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!"));
63 // _ptrMesh->addDriver(*this); // OU RECUPERER L'ID.
64 MESSAGE_MED("VTK_MESH_DRIVER::VTK_MESH_DRIVER(const string & fileName, MESH * ptrMesh) : "
65 << "WARNING this driver is only used to write in VTK format So the object can not be instantied using a file!");
67 //_vtkFile = new ofstream();
72 VTK_MESH_DRIVER::VTK_MESH_DRIVER(const VTK_MESH_DRIVER & driver):
74 _ptrMesh(driver._ptrMesh),
75 _meshName(driver._meshName)
77 // next string commented by skl for bug NPAL14840
78 //_ptrMesh->addDriver(*this);
79 //_vtkFile = new ofstream();
84 VTK_MESH_DRIVER::~VTK_MESH_DRIVER()
86 const char* LOC = "VTK_MESH_DRIVER::~VTK_MESH_DRIVER()";
101 SCRUTE_MED(_vtkFile);
106 void VTK_MESH_DRIVER::openConst() const throw (MEDEXCEPTION)
108 const char * LOC = "VTK_MESH_DRIVER::openConst() " ;
111 MESSAGE_MED(LOC<<" : _fileName.c_str : "<< _fileName.c_str()<<",mode : "<< _accessMode);
113 if ( _fileName == "" )
114 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
115 << "_fileName is |\"\"|, please set a correct fileName before calling open()"));
117 if ( DRIVERFACTORY::getVtkBinaryFormatForWriting() )
127 _binaryFile = new _VTK_BinaryWriter( _fileName );
128 if (!_binaryFile->open())
132 throw MED_EXCEPTION( LOCALIZED( STRING(LOC) << "Could not open file "<< _fileName));
146 _vtkFile = new ofstream();
147 if (!(*_vtkFile).is_open())
148 (*_vtkFile).open(_fileName.c_str()) ;
154 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not open file "<< _fileName));
160 void VTK_MESH_DRIVER::open() {
164 void VTK_MESH_DRIVER::closeConst() const throw (MEDEXCEPTION)
166 const char * LOC = "VTK_MESH_DRIVER::closeConst() " ;
171 if ((*_vtkFile).is_open())
174 if ( (*_vtkFile) && _vtkFile->is_open() )
175 throw MED_EXCEPTION( LOCALIZED( STRING(LOC) << "Could not close file "<< _fileName));
179 _binaryFile->close();
181 ((VTK_MESH_DRIVER*)this)->_binaryFile = 0;
186 void VTK_MESH_DRIVER::close() {
190 void VTK_MESH_DRIVER::setMeshName(const string & meshName) { _meshName = meshName; }
191 string VTK_MESH_DRIVER::getMeshName() const { return _meshName; }
193 void VTK_MESH_DRIVER::read(void) throw (MEDEXCEPTION)
195 const char * LOC = "VTK_MESH_DRIVER::read() : " ;
200 throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "This driver is only used to write in VTK format !"));
206 void VTK_MESH_DRIVER::write(void) const
209 const char * LOC = "void VTK_MESH_DRIVER::write(void) const : ";
213 throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Mesh is NULL"));
215 // Well we must open vtk file first, because there are
216 // no other driver than MED for VTK that do it !
218 int SpaceDimension = _ptrMesh->getSpaceDimension() ;
219 int NumberOfNodes = _ptrMesh->getNumberOfNodes() ;
220 if ( SpaceDimension < 1 )
221 throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Mesh is empty"));
225 const MESH* mesh = _ptrMesh->convertInMESH();
227 const char* header = "# vtk DataFile Version 2.0\n";
228 const char* title = "maillage from MedMemory\n";
229 const char* dataset = "DATASET UNSTRUCTURED_GRID\n";
230 if ( _vtkFile ) // ASCII
232 (*_vtkFile) << header ;
233 (*_vtkFile) << title ;
234 (*_vtkFile) << "ASCII" << endl ;
235 (*_vtkFile) << dataset ;
236 // put points (all point are in 3D, so if we are in 1D or 2D, we complete by zero !
237 (*_vtkFile) << "POINTS " << NumberOfNodes << " float" << endl ;
238 const double *coordinate = mesh->getCoordinates(MED_FULL_INTERLACE) ;
239 string missingCoord = SpaceDimension==3 ? "" : SpaceDimension==2 ? "0" : "0 0";
240 for (int i=0;i<NumberOfNodes;i++)
242 for (int j=0;j<SpaceDimension;j++)
243 (*_vtkFile) << coordinate[i*SpaceDimension+j] << " ";
244 (*_vtkFile) << missingCoord << endl;
249 const char* format = "BINARY\n";
250 writeBinary( header, strlen(header) );
251 writeBinary( title, strlen(title) );
252 writeBinary( format, strlen(format) );
253 writeBinary( dataset, strlen(dataset) );
255 // put points (all point are in 3D, so if we are in 1D or 2D, we complete by zero !
256 //sprintf(buf,"POINTS %d double\n", NumberOfNodes);
257 sprintf(buf,"POINTS %d float\n", NumberOfNodes);
258 writeBinary( buf, strlen(buf) );
259 const double *coordinate = mesh->getCoordinates(MED_FULL_INTERLACE) ;
260 //PointerOf<double> coordBuf( SpaceDimension==3 ? 0 : NumberOfNodes * 3 );
261 //double * toCoord = coordBuf;
262 PointerOf<float> coordBuf( NumberOfNodes * 3 );
263 float * toCoord = coordBuf;
264 switch( SpaceDimension )
267 for (int i=0;i<NumberOfNodes;i++)
269 *toCoord++ = (float)*coordinate++;
270 *toCoord++ = (float)*coordinate++;
271 *toCoord++ = (float)*coordinate++;
275 for (int i=0;i<NumberOfNodes;i++)
277 *toCoord++ = (float)*coordinate++;
278 *toCoord++ = (float)*coordinate++;
283 for (int i=0;i<NumberOfNodes;i++)
285 *toCoord++ = (float)*coordinate++;
290 // coordBuf.set( coordinate );
293 // for (int i=0;i<NumberOfNodes;i++)
295 // *toCoord++ = *coordinate++;
296 // *toCoord++ = *coordinate++;
301 // for (int i=0;i<NumberOfNodes;i++)
303 // *toCoord++ = *coordinate++;
309 //writeBinary( (double*) coordBuf, NumberOfNodes * 3 );
310 writeBinary( (float*) coordBuf, NumberOfNodes * 3 );
313 // we put connectivity
314 // how many cells and how many value in connectivity :
315 int cells_types_count = mesh->getNumberOfTypes(MED_CELL) ;
316 int cells_sum = mesh->getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) ;
317 const CELLMODEL * cells_type = mesh->getCellsTypes(MED_CELL) ;
319 const int * connectivityIndex = mesh->getConnectivityIndex(MED_NODAL,MED_CELL) ;
320 int connectivity_sum = connectivityIndex[cells_sum]-1 ;
322 sprintf(buf,"\nCELLS %d %d\n", cells_sum, connectivity_sum+cells_sum);
326 writeBinary( buf, strlen(buf) );
328 for (int i=0;i<cells_types_count;i++) {
329 int *filter = (int*) NULL ; // index in vtk connectivity
330 switch (cells_type[i].getType())
333 filter = new int[1] ;
338 filter = new int[2] ;
347 filter = new int[3] ;
354 filter = new int[4] ;
368 filter = new int[4] ;
371 filter[2] = 3 ; // 3td element in med are 4th in vtk (array begin at 0 !)
372 filter[3] = 2 ; // 4th element in med are 3rd in vtk (array begin at 0 !)
376 filter = new int[5] ;
378 filter[1] = 3 ; // 2nd element in med are 4th in vtk (array begin at 0 !)
380 filter[3] = 1 ; // 4th element in med are 2nd in vtk (array begin at 0 !)
385 filter = new int[6] ;
395 filter = new int[8] ;
423 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": MED element type not supported yet : " << cells_type[i].getName() ) ) ;
424 int nodes_cell = cells_type[i].getNumberOfNodes();
425 int numberOfCell = mesh->getNumberOfElements(MED_CELL,cells_type[i].getType()) ;
426 const int * connectivityArray = mesh->getConnectivity(MED_NODAL,MED_CELL,cells_type[i].getType());
429 for (int j=0;j<numberOfCell;j++)
431 (*_vtkFile) << nodes_cell << " " ;
432 for (int k=0;k<nodes_cell;k++)
433 (*_vtkFile) << connectivityArray[j*nodes_cell+filter[k]] - 1 << " " ;
434 (*_vtkFile) << endl ;
439 int dataSize = numberOfCell * ( nodes_cell+1 );
440 PointerOf<int> cellData( dataSize );
441 for (int *pCellData = cellData, j = 0; j < numberOfCell; j++)
443 *pCellData++ = nodes_cell;
444 for (int k=0;k<nodes_cell;k++)
445 *pCellData++ = connectivityArray[j*nodes_cell+filter[k]] - 1;
447 writeBinary( (int*) cellData, dataSize );
452 sprintf(buf,"\nCELL_TYPES %d\n", cells_sum);
456 writeBinary( buf, strlen(buf) );
458 for (int i=0;i<cells_types_count;i++) {
460 switch (cells_type[i].getType())
462 case MED_POINT1 :vtkType = 1 ;break ;
463 case MED_SEG2 :vtkType = 3 ;break ;
464 case MED_SEG3 :vtkType = 0 ;break ;
465 case MED_TRIA3 :vtkType = 5 ;break ;
466 case MED_QUAD4 :vtkType = 9 ;break ;
467 case MED_TRIA6 :vtkType = 0 ;break ;
468 case MED_QUAD8 :vtkType = 0 ;break ;
469 case MED_TETRA4 :vtkType = 10 ;break ;
470 case MED_PYRA5 :vtkType = 14 ;break ;
471 case MED_PENTA6 :vtkType = 13 ;break ;
472 case MED_HEXA8 :vtkType = 12 ;break ;
473 case MED_TETRA10 :vtkType = 0 ;break ;
474 case MED_PYRA13 :vtkType = 0 ;break ;
475 case MED_PENTA15 :vtkType = 0 ;break ;
476 case MED_HEXA20 :vtkType = 0 ;break ;
477 default :vtkType = 0 ;break ;
480 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": MED element type not supported yet : " << cells_type[i].getType() ) ) ;
481 int numberOfCell = mesh->getNumberOfElements(MED_CELL,cells_type[i].getType()) ;
484 for (int j=0;j<numberOfCell;j++)
485 (*_vtkFile) << vtkType << endl ;
489 vector< int > type( numberOfCell, vtkType );
490 writeBinary( &type[0], type.size() );
493 mesh->removeReference();
500 GENDRIVER * VTK_MESH_DRIVER::copy(void) const
502 return new VTK_MESH_DRIVER(*this);
505 //////////////////////////////////////////////////////////////////////////////////////////
507 //////////////////////////////////////////////////////////////////////////////////////////
509 _VTK_BinaryWriter::_VTK_BinaryWriter(const std::string file):_fileName(file),_binaryFile(0)
513 bool _VTK_BinaryWriter::open(bool append) const
517 // workaround to create file with good access rights
519 fstream(_fileName.c_str(), ios_base::out);
522 _VTK_BinaryWriter* mutableMe =(_VTK_BinaryWriter*) this;
525 if ( append ) append_flag = _O_APPEND;
526 mutableMe->_binaryFile = ::_open (_fileName.c_str(), _O_WRONLY|_O_BINARY|append_flag);
528 if ( append ) append_flag = O_APPEND;
529 mutableMe->_binaryFile = ::open (_fileName.c_str(), O_WRONLY|append_flag);
532 mutableMe->_binaryFile = 0;
537 bool _VTK_BinaryWriter::close() const
542 ::_close (_binaryFile);
544 ::close (_binaryFile);
546 ((_VTK_BinaryWriter*)this)->_binaryFile = 0;