]> SALOME platform Git repositories - modules/med.git/blob - src/MEDMEM/MEDMEM_VtkMeshDriver.cxx
Salome HOME
Fix problem of make distcheck
[modules/med.git] / src / MEDMEM / MEDMEM_VtkMeshDriver.cxx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "MEDMEM_VtkMeshDriver.hxx"
24
25 #include "MEDMEM_DriversDef.hxx"
26
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"
35
36 #include <fcntl.h>
37 #include <sstream>
38
39 using namespace std;
40 using namespace MEDMEM;
41 using namespace MED_EN;
42
43 VTK_MESH_DRIVER::VTK_MESH_DRIVER(): GENDRIVER(VTK_DRIVER), 
44                                     _ptrMesh((MESH * const)MED_NULL)
45 {
46   //_vtkFile = new ofstream();
47   _vtkFile = 0;
48   _binaryFile = 0;
49   // What about _id in Gendriver ?
50   // _driverType ???
51 }
52
53 VTK_MESH_DRIVER::VTK_MESH_DRIVER(const string & fileName, const GMESH *  ptrMesh) :
54   GENDRIVER(fileName, WRONLY, VTK_DRIVER),
55   _ptrMesh(ptrMesh)
56 {
57
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
60
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!"));
62
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!");
66
67   //_vtkFile = new ofstream();
68   _vtkFile = 0;
69   _binaryFile = 0;
70 }
71
72 VTK_MESH_DRIVER::VTK_MESH_DRIVER(const VTK_MESH_DRIVER & driver): 
73   GENDRIVER(driver),
74   _ptrMesh(driver._ptrMesh),
75   _meshName(driver._meshName)
76 {
77   // next string commented by skl for bug NPAL14840
78   //_ptrMesh->addDriver(*this);
79   //_vtkFile = new ofstream();
80   _vtkFile = 0;
81   _binaryFile = 0;
82 }
83
84 VTK_MESH_DRIVER::~VTK_MESH_DRIVER()
85 {
86   const char* LOC = "VTK_MESH_DRIVER::~VTK_MESH_DRIVER()";
87   BEGIN_OF_MED(LOC);
88
89   close();
90
91   SCRUTE_MED(_vtkFile);
92
93   if ( _vtkFile )
94     delete _vtkFile ;
95   if ( _binaryFile )
96     delete _binaryFile;
97
98   _vtkFile = 0;
99   _binaryFile = 0;
100
101   SCRUTE_MED(_vtkFile);
102
103   END_OF_MED(LOC);
104 }
105
106 void VTK_MESH_DRIVER::openConst() const throw (MEDEXCEPTION)
107 {
108   const char * LOC = "VTK_MESH_DRIVER::openConst() " ;
109   BEGIN_OF_MED(LOC);
110
111   MESSAGE_MED(LOC<<" : _fileName.c_str : "<< _fileName.c_str()<<",mode : "<< _accessMode);
112
113   if ( _fileName == "" )
114     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
115                                      << "_fileName is |\"\"|, please set a correct fileName before calling open()"));
116
117   if ( DRIVERFACTORY::getVtkBinaryFormatForWriting() )
118     {
119       if ( _vtkFile )
120         {
121           closeConst();
122           delete _vtkFile;
123           _vtkFile = 0;
124         }
125       if ( !_binaryFile )
126         {
127           _binaryFile = new _VTK_BinaryWriter( _fileName );
128           if (!_binaryFile->open())
129             {
130               delete _binaryFile;
131               _binaryFile = 0;
132               throw MED_EXCEPTION( LOCALIZED( STRING(LOC) << "Could not open file "<< _fileName));
133             }
134         }
135     }
136   else
137     {
138       if ( _binaryFile )
139         {
140           closeConst();
141           delete _binaryFile;
142           _binaryFile = 0;
143         }
144  
145       if (!_vtkFile )
146         _vtkFile = new ofstream();
147       if (!(*_vtkFile).is_open())
148         (*_vtkFile).open(_fileName.c_str()) ; 
149
150       if (!(*_vtkFile))
151         {
152           delete _vtkFile;
153           _vtkFile = 0;
154           throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not open file "<< _fileName));
155         }
156     }
157   END_OF_MED(LOC);
158 }
159
160 void VTK_MESH_DRIVER::open() {
161   openConst() ;
162 }
163
164 void VTK_MESH_DRIVER::closeConst() const throw (MEDEXCEPTION)
165 {
166   const char * LOC = "VTK_MESH_DRIVER::closeConst() " ;
167   BEGIN_OF_MED(LOC);
168
169   if ( _vtkFile )
170     {
171       if ((*_vtkFile).is_open())
172         (*_vtkFile).close();
173   
174       if ( (*_vtkFile) && _vtkFile->is_open() )
175         throw MED_EXCEPTION( LOCALIZED( STRING(LOC) << "Could not close file "<< _fileName));
176     }
177   if ( _binaryFile )
178     {
179       _binaryFile->close();
180       delete _binaryFile;
181       ((VTK_MESH_DRIVER*)this)->_binaryFile = 0;
182     }
183   END_OF_MED(LOC);
184 }
185
186 void VTK_MESH_DRIVER::close() {
187   closeConst() ;
188 }
189
190 void    VTK_MESH_DRIVER::setMeshName(const string & meshName) { _meshName = meshName; }
191 string  VTK_MESH_DRIVER::getMeshName() const { return _meshName; }
192
193 void VTK_MESH_DRIVER::read(void) throw (MEDEXCEPTION)
194 {
195   const char * LOC = "VTK_MESH_DRIVER::read() : " ;
196   BEGIN_OF_MED(LOC);
197
198   // Send an exception
199
200   throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "This driver is only used to write in VTK format !"));
201
202   END_OF_MED(LOC);
203 }
204
205
206 void VTK_MESH_DRIVER::write(void) const
207   throw (MEDEXCEPTION)
208 {
209   const char * LOC = "void VTK_MESH_DRIVER::write(void) const : ";
210   BEGIN_OF_MED(LOC);
211
212   if ( !_ptrMesh )
213     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Mesh is NULL"));
214
215   // Well we must open vtk file first, because there are
216   // no other driver than MED for VTK that do it !
217
218   int SpaceDimension = _ptrMesh->getSpaceDimension() ;
219   int NumberOfNodes  = _ptrMesh->getNumberOfNodes() ;
220   if ( SpaceDimension < 1 )
221     throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Mesh is empty"));
222
223   openConst();
224
225   const MESH* mesh = _ptrMesh->convertInMESH();
226   char buf[256];
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
231     {
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++)
241         {
242           for (int j=0;j<SpaceDimension;j++)
243             (*_vtkFile) << coordinate[i*SpaceDimension+j] << " ";
244           (*_vtkFile) << missingCoord << endl;
245         }
246     }
247   else // BINARY
248     {
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) );
254
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 )
265         {
266         case 3:
267           for (int i=0;i<NumberOfNodes;i++)
268             {
269               *toCoord++ = (float)*coordinate++;
270               *toCoord++ = (float)*coordinate++;
271               *toCoord++ = (float)*coordinate++;
272             }
273           break;
274         case 2:
275           for (int i=0;i<NumberOfNodes;i++)
276             {
277               *toCoord++ = (float)*coordinate++;
278               *toCoord++ = (float)*coordinate++;
279               *toCoord++ = 0;
280             }
281           break;
282         case 1:
283           for (int i=0;i<NumberOfNodes;i++)
284             {
285               *toCoord++ = (float)*coordinate++;
286               *toCoord++ = 0;
287               *toCoord++ = 0;
288             }
289           break;
290 //           coordBuf.set( coordinate );
291 //           break;
292 //         case 2:
293 //           for (int i=0;i<NumberOfNodes;i++)
294 //             {
295 //               *toCoord++ = *coordinate++;
296 //               *toCoord++ = *coordinate++;
297 //               *toCoord++ = 0;
298 //             }
299 //           break;
300 //         case 1:
301 //           for (int i=0;i<NumberOfNodes;i++)
302 //             {
303 //               *toCoord++ = *coordinate++;
304 //               *toCoord++ = 0;
305 //               *toCoord++ = 0;
306 //             }
307 //           break;
308         }
309       //writeBinary( (double*) coordBuf, NumberOfNodes * 3 );
310       writeBinary( (float*) coordBuf, NumberOfNodes * 3 );
311     }
312
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) ;
318
319   const int * connectivityIndex = mesh->getConnectivityIndex(MED_NODAL,MED_CELL) ;
320   int          connectivity_sum =  connectivityIndex[cells_sum]-1 ;
321
322   sprintf(buf,"\nCELLS %d %d\n", cells_sum, connectivity_sum+cells_sum);
323   if ( _vtkFile )
324     (*_vtkFile) << buf ;
325   else
326     writeBinary( buf, strlen(buf) );
327
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())
331       {
332       case MED_POINT1  : {
333         filter = new int[1] ;
334         filter[0] = 0 ;
335         break ;
336       }
337       case MED_SEG2    : {
338         filter = new int[2] ;
339         filter[0] = 0 ;
340         filter[1] = 1 ;
341         break ;
342       }
343       case MED_SEG3    : {  
344         break ;
345       }
346       case MED_TRIA3   : {
347         filter = new int[3] ;
348         filter[0] = 0 ;
349         filter[1] = 1 ;
350         filter[2] = 2 ;
351         break ;
352       }
353       case MED_QUAD4   : {
354         filter = new int[4] ;
355         filter[0] = 0 ;
356         filter[1] = 1 ;
357         filter[2] = 2 ;
358         filter[3] = 3 ;
359         break ;
360       }
361       case MED_TRIA6   : {
362         break ;
363       }
364       case MED_QUAD8   : {
365         break ;
366       }
367       case MED_TETRA4  : {
368         filter = new int[4] ;
369         filter[0] = 0 ;
370         filter[1] = 1 ;
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 !)
373         break ;
374       }
375       case MED_PYRA5   : {
376         filter = new int[5] ;
377         filter[0] = 0 ;
378         filter[1] = 3 ;  // 2nd element in med are 4th in vtk (array begin at 0 !)
379         filter[2] = 2 ;
380         filter[3] = 1 ;  // 4th element in med are 2nd in vtk (array begin at 0 !)
381         filter[4] = 4 ;
382         break ;
383       }
384       case MED_PENTA6  : {
385         filter = new int[6] ;
386         filter[0] = 0 ;
387         filter[1] = 1 ;
388         filter[2] = 2 ;
389         filter[3] = 3 ;
390         filter[4] = 4 ;
391         filter[5] = 5 ;
392         break ;
393       }
394       case MED_HEXA8   : {
395         filter = new int[8] ;
396         filter[0] = 0 ;
397         filter[1] = 3 ;
398         filter[2] = 2 ;
399         filter[3] = 1 ;
400         filter[4] = 4 ;
401         filter[5] = 7 ;
402         filter[6] = 6 ;
403         filter[7] = 5 ;
404         break ;
405       }
406       case MED_TETRA10 : {
407         break ;
408       }
409       case MED_PYRA13  : {
410         break ;
411       }
412       case MED_PENTA15 : {
413         break ;
414       }
415       case MED_HEXA20  : {
416         break ;
417       }
418       default : { 
419         break ;
420       }
421       }
422     if (filter==NULL) 
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());
427     if ( _vtkFile )
428       {
429         for (int j=0;j<numberOfCell;j++)
430           {
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 ;
435           }
436       }
437     else // BINARY
438       {
439         int dataSize = numberOfCell * ( nodes_cell+1 );
440         PointerOf<int> cellData( dataSize );
441         for (int *pCellData = cellData, j = 0; j < numberOfCell; j++)
442           {
443             *pCellData++ = nodes_cell;
444             for (int k=0;k<nodes_cell;k++)
445               *pCellData++ = connectivityArray[j*nodes_cell+filter[k]] - 1;
446           }
447         writeBinary( (int*) cellData, dataSize );
448       }
449     if (filter != NULL)
450       delete[] filter ;
451   }
452   sprintf(buf,"\nCELL_TYPES %d\n", cells_sum);
453   if ( _vtkFile )
454     (*_vtkFile) << buf ;
455   else
456     writeBinary( buf, strlen(buf) );
457
458   for (int i=0;i<cells_types_count;i++) {
459     int vtkType = 0 ;
460     switch (cells_type[i].getType())
461       {
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 ;
478       }
479     if (vtkType == 0)
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()) ;
482     if ( _vtkFile )
483       {
484         for (int j=0;j<numberOfCell;j++)
485           (*_vtkFile) << vtkType << endl ;
486       }
487     else
488       {
489         vector< int > type( numberOfCell, vtkType );
490         writeBinary( &type[0], type.size() );
491       }
492   }
493   mesh->removeReference();
494
495   closeConst();
496
497   END_OF_MED(LOC);
498
499
500 GENDRIVER * VTK_MESH_DRIVER::copy(void) const
501 {
502   return new VTK_MESH_DRIVER(*this);
503 }
504
505 //////////////////////////////////////////////////////////////////////////////////////////
506 // _VTK_BinaryWriter
507 //////////////////////////////////////////////////////////////////////////////////////////
508
509 _VTK_BinaryWriter::_VTK_BinaryWriter(const std::string file):_fileName(file),_binaryFile(0)
510 {
511 }
512
513 bool _VTK_BinaryWriter::open(bool append) const
514 {
515   if ( !_binaryFile )
516     {
517       // workaround to create file with good access rights
518       if ( !append )
519         fstream(_fileName.c_str(), ios_base::out);
520
521       // opening
522       _VTK_BinaryWriter* mutableMe =(_VTK_BinaryWriter*) this;
523       int append_flag = 0;
524 #ifdef WIN32
525       if ( append ) append_flag = _O_APPEND;
526       mutableMe->_binaryFile = ::_open (_fileName.c_str(), _O_WRONLY|_O_BINARY|append_flag);
527 #else
528       if ( append ) append_flag = O_APPEND;
529       mutableMe->_binaryFile = ::open (_fileName.c_str(), O_WRONLY|append_flag);
530 #endif
531       if (_binaryFile < 0)
532         mutableMe->_binaryFile = 0;
533     }
534   return _binaryFile;
535 }
536
537 bool _VTK_BinaryWriter::close() const
538 {
539   if ( _binaryFile )
540     {
541 #ifdef WIN32
542       ::_close (_binaryFile);
543 #else
544       ::close (_binaryFile);
545 #endif
546       ((_VTK_BinaryWriter*)this)->_binaryFile = 0;
547     }
548   return true;
549 }