]> SALOME platform Git repositories - modules/med.git/blob - src/MEDMEM/MEDMEM_VtkFieldDriver.hxx
Salome HOME
Final version V2_0_1 which works with Med File V2.1 and the KERNEL
[modules/med.git] / src / MEDMEM / MEDMEM_VtkFieldDriver.hxx
1 #ifndef VTK_FIELD_DRIVER_HXX
2 #define VTK_FIELD_DRIVER_HXX
3
4 #include <string>
5 #include <fstream>
6 #include <sstream>
7
8 #include "MEDMEM_define.hxx"
9
10 #include "MEDMEM_GenDriver.hxx"
11 #include "utilities.h"
12
13 #include "MEDMEM_STRING.hxx"
14 #include "MEDMEM_Exception.hxx"
15 #include "MEDMEM_Unit.hxx"
16 #include "MEDMEM_Array.hxx"
17 #include "MEDMEM_Support.hxx"
18 //#include "MEDMEM_Field.hxx"
19 #include "MEDMEM_Mesh.hxx"
20 #include "MEDMEM_CellModel.hxx"
21
22 using namespace MEDMEM ;
23
24
25 /*!
26
27   Driver Med for FIELD.
28
29   Generic part : implement open and close methods.
30
31 */
32
33 namespace MEDMEM {
34 template <class T> class FIELD;
35 template <class T> class VTK_FIELD_DRIVER : public GENDRIVER
36 {
37 protected:
38   
39   FIELD<T> *     _ptrField;
40   mutable ofstream *        _vtkFile ;
41   string         _fieldName;
42   int            _fieldNum;
43
44 public :
45
46   // all MED cell type ?? Classe de Définition ??
47   //   static const medGeometryElement all_cell_type[MED_NBR_GEOMETRIE_MAILLE];
48   
49   //   static const char * const all_cell_type_tab [MED_NBR_GEOMETRIE_MAILLE];
50   
51   /*!
52     Constructor.
53   */
54   VTK_FIELD_DRIVER():GENDRIVER(),
55                      _ptrField((FIELD<T> *)MED_NULL), _fieldName(""),
56                      _fieldNum(MED_INVALID)
57   {
58     const char * LOC = "VTK_FIELD_DRIVER::VTK_FIELD_DRIVER() ";
59     BEGIN_OF(LOC);
60
61     _vtkFile = new ofstream();
62
63     END_OF(LOC);
64   }
65   /*!
66     Constructor.
67   */
68   VTK_FIELD_DRIVER(const string & fileName, FIELD<T> * ptrField)
69     : GENDRIVER(fileName,MED_WRONLY),
70       _ptrField((FIELD<T> *) ptrField),
71       _fieldName(fileName),_fieldNum(MED_INVALID) 
72   {
73     const char * LOC = "VTK_FIELD_DRIVER::VTK_FIELD_DRIVER(const string & fileName, FIELD<T> * ptrField) ";
74     BEGIN_OF(LOC);
75
76     _vtkFile = new ofstream();
77
78     END_OF(LOC);
79   }
80
81   /*!
82     Copy constructor.
83   */
84   VTK_FIELD_DRIVER(const VTK_FIELD_DRIVER & fieldDriver):
85     GENDRIVER(fieldDriver),
86     _ptrField(fieldDriver._ptrField),
87     _fieldName(fieldDriver._fieldName),
88     _fieldNum(fieldDriver._fieldNum) 
89   {
90     _ptrField->addDriver(*this);
91     _vtkFile = new ofstream();
92   }
93
94   /*!
95     Destructor.
96   */
97   ~VTK_FIELD_DRIVER()
98   {
99   const char * LOC ="VTK_FIELD_DRIVER::~VTK_FIELD_DRIVER()";
100   BEGIN_OF(LOC);
101
102   close();
103
104   SCRUTE(_vtkFile);
105
106   delete _vtkFile ;
107
108   SCRUTE(_vtkFile);
109
110   END_OF(LOC);
111   }
112
113   void openConst() const throw (MEDEXCEPTION)
114   {
115     const char * LOC = "VTK_FIELD_DRIVER::openConst()" ;
116     BEGIN_OF(LOC);
117
118     MESSAGE(LOC<<" : _fileName.c_str : "<< _fileName.c_str()<<",mode : "<< _accessMode);
119
120     if ( _fileName == "" )
121       throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
122                                        << "_fileName is |\"\"|, please set a correct fileName before calling open()"
123                                        )
124                             );
125
126     if (!(*_vtkFile).is_open())
127       (*_vtkFile).open(_fileName.c_str()) ; 
128 //    if (*_vtkFile)
129 //      _status = MED_OPENED ;
130 //    else
131
132
133     SCRUTE((*_vtkFile).is_open());
134     SCRUTE(_vtkFile);
135
136
137
138     if (!(*_vtkFile))
139       throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not open file "
140                                        << _fileName)
141                             );
142     END_OF(LOC);
143   }
144
145   void openConstAppend() const throw (MEDEXCEPTION)
146   {
147     const char * LOC = "VTK_FIELD_DRIVER::openConstAppend()" ;
148     BEGIN_OF(LOC);
149
150     MESSAGE(LOC<<" : _fileName.c_str : "<< _fileName.c_str()<<",mode : "<< _accessMode);
151
152     if ( _fileName == "" )
153       throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
154                                        << "_fileName is |\"\"|, please set a correct fileName before calling open()"
155                                        )
156                             );
157
158     SCRUTE((*_vtkFile).is_open());
159
160     if (!(*_vtkFile).is_open())
161       {
162         MESSAGE(LOC<<"The file is already close and it is opened with the right option");
163         (*_vtkFile).open(_fileName.c_str(), ofstream::out | ofstream::app) ; 
164       }
165     else
166       {
167         MESSAGE(LOC<<"The file is still open, it is closed to make sure that it will be opened with the right option");
168         //      closeConst();
169
170
171         (*_vtkFile).close() ;
172
173         _vtkFile->open(_fileName.c_str(), ofstream::out | ofstream::app) ; 
174       }
175 //    if (*_vtkFile)
176 //      _status = MED_OPENED ;
177 //    else
178
179
180     SCRUTE((*_vtkFile).is_open());
181     SCRUTE(_vtkFile);
182
183
184
185     if (!(*_vtkFile))
186       throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not open file "
187                                        << _fileName)
188                             );
189     END_OF(LOC);
190   }
191
192   void open() throw (MEDEXCEPTION)
193   {
194     openConst() ;
195   }
196
197   void openAppend() throw (MEDEXCEPTION)
198   {
199     openConstAppend() ;
200   }
201
202   void closeConst() const throw (MEDEXCEPTION)
203   {
204     const char * LOC = "VTK_FIELD_DRIVER::closeConst() " ;
205     BEGIN_OF(LOC);
206
207     SCRUTE(_vtkFile);
208     SCRUTE(*_vtkFile);
209
210
211     if ((*_vtkFile).is_open())
212       (*_vtkFile).close();
213   
214 //    if (*_vtkFile)
215 //      _status = MED_CLOSED ;
216 //    else
217
218     SCRUTE(_vtkFile);
219     SCRUTE(*_vtkFile);
220
221     if (!(*_vtkFile))
222       throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not close file "
223                                        << _fileName)
224                             );
225
226     END_OF(LOC);
227   }
228
229   void close() {
230     closeConst() ;
231   }
232
233   /*!
234     Set the name of the FIELD asked in file.
235
236     It could be different than the name of the FIELD object.
237   */
238   void   setFieldName(const string & fieldName) ;
239
240   /*!
241     Get the name of the FIELD asked in file.
242   */
243   string getFieldName() const ;
244
245   /*!
246     Return a MEDEXCEPTION : it is the write-only driver.
247   */
248   void read ( void ) throw (MEDEXCEPTION) ;
249
250   /*!
251     Write FIELD in the specified file, with its mesh through its support
252     which has to be on all entities (excluding the faces in 3d and edges
253     in 2d).
254   */
255   void write( void ) const throw (MEDEXCEPTION) ;
256
257   /*!
258     Write FIELD in the specified file, the mesh is supposed to be
259     written in this file. The field support has to be on all entities
260     (excluding the faces in 3d and edges in 2d).
261   */
262   void writeAppend( void ) const throw (MEDEXCEPTION);
263
264 private:
265   GENDRIVER * copy ( void ) const ;
266
267 };
268 };
269
270 /*-------------------------*/
271 /* template implementation */
272 /*-------------------------*/
273
274 /*--------------------- DRIVER PART -------------------------------*/
275
276 using namespace MEDMEM;
277 template <class T> void VTK_FIELD_DRIVER<T>::setFieldName(const string & fieldName)
278 {
279   _fieldName = fieldName; 
280 }
281
282 template <class T> string  VTK_FIELD_DRIVER<T>::getFieldName() const
283 {
284   return _fieldName;
285 }
286
287 template <class T> GENDRIVER * VTK_FIELD_DRIVER<T>::copy(void) const
288 {
289   VTK_FIELD_DRIVER<T> * myDriver = new VTK_FIELD_DRIVER<T>(*this);
290
291   return myDriver ;
292 }
293
294 template <class T> void VTK_FIELD_DRIVER<T>::read (void)
295   throw (MEDEXCEPTION)
296 {
297   throw MEDEXCEPTION("VTK_FIELD_DRIVER::read : Can't read with a VTK driver because it is write only driver !");
298 }
299
300 template <class T> void VTK_FIELD_DRIVER<T>::write(void) const
301   throw (MEDEXCEPTION)
302 {
303   const char * LOC = "VTK_FIELD_DRIVER::write(void) const " ;
304   BEGIN_OF(LOC);
305
306   // we get the Support and its associated Mesh
307
308   const SUPPORT * supportField = _ptrField->getSupport();
309   MESH * meshField = supportField->getMesh();
310
311   // Well we must open vtk file first, because there are
312   // no other driver than MED for VTK that do it !
313   openConst() ;
314
315   // could we put more than one Mesh ?????
316   (*_vtkFile) << "# vtk DataFile Version 2.0" << endl 
317            << "maillage from MedMemory"  << endl ;
318   // only ASCII for the moment (binary came later :-)
319   (*_vtkFile) << "ASCII" << endl ;
320
321   (*_vtkFile) << "DATASET UNSTRUCTURED_GRID" << endl ;
322   // put points (all point are in 3D, so if we are in 1D or 2D, we complete by zero !
323   int SpaceDimension = meshField->getSpaceDimension() ;
324   int NumberOfNodes = meshField->getNumberOfNodes() ;
325   (*_vtkFile) << "POINTS " << NumberOfNodes << " float" << endl ;
326   const double *coordinate = meshField->getCoordinates(MED_FULL_INTERLACE) ;
327   for (int i=0;i<NumberOfNodes;i++) {
328     for (int j=0;j<SpaceDimension;j++)
329       (*_vtkFile) << coordinate[i*SpaceDimension+j] << " " ;
330     if (SpaceDimension==1) 
331       (*_vtkFile) << "0 0" ;
332     if (SpaceDimension==2) 
333       (*_vtkFile) << "0" ;
334     (*_vtkFile) << endl ;
335   }
336
337   // we put connectivity
338   // how many cells and how many value in connectivity :
339   int cells_types_count = meshField->getNumberOfTypes(MED_CELL) ;
340   //  int * cells_count = meshField->get_cells_count() ;
341   //  int cells_sum = cells_count[cells_types_count] ;
342   int cells_sum = meshField->getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) ;
343   const CELLMODEL * cells_type = meshField->getCellsTypes(MED_CELL) ;
344   //  int connectivity_sum = 0 ;
345
346   //const int * connectivity = meshField->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,MED_CELL,MED_ALL_ELEMENTS) ; !! UNUSED VARIABLE !!
347   const int * connectivityIndex = meshField->getConnectivityIndex(MED_NODAL,MED_CELL) ;
348
349   int connectivity_sum =  connectivityIndex[cells_sum]-1 ;
350
351   (*_vtkFile) << "CELLS " << cells_sum << " " << connectivity_sum+cells_sum << endl ;
352   // we put connectivity
353   for (int i=0;i<cells_types_count;i++) {
354     int *filter = (int*) NULL ; // index in vtk connectivity
355     switch (cells_type[i].getType())
356       {
357       case MED_POINT1  : {
358         filter = new int[1] ;
359         filter[0] = 0 ;
360         break ;
361       }
362       case MED_SEG2    : {
363         filter = new int[2] ;
364         filter[0] = 0 ;
365         filter[1] = 1 ;
366         break ;
367       }
368       case MED_SEG3    : {  
369         break ;
370       }
371       case MED_TRIA3   : {
372         filter = new int[3] ;
373         filter[0] = 0 ;
374         filter[1] = 1 ;
375         filter[2] = 2 ;
376         break ;
377       }
378       case MED_QUAD4   : {
379         filter = new int[4] ;
380         filter[0] = 0 ;
381         filter[1] = 1 ;
382         filter[2] = 2 ;
383         filter[3] = 3 ;
384         break ;
385       }
386       case MED_TRIA6   : {
387         break ;
388       }
389       case MED_QUAD8   : {
390         break ;
391       }
392       case MED_TETRA4  : {
393         filter = new int[4] ;
394         filter[0] = 0 ;
395         filter[1] = 1 ;
396         filter[2] = 3 ;  // 3td element in med are 4th in vtk (array begin at 0 !)
397         filter[3] = 2 ;  // 4th element in med are 3rd in vtk (array begin at 0 !)
398         break ;
399       }
400       case MED_PYRA5   : {
401         filter = new int[5] ;
402         filter[0] = 0 ;
403         filter[1] = 3 ;  // 2nd element in med are 4th in vtk (array begin at 0 !)
404         filter[2] = 2 ;
405         filter[3] = 1 ;  // 4th element in med are 2nd in vtk (array begin at 0 !)
406         filter[4] = 4 ;
407         break ;
408       }
409       case MED_PENTA6  : {
410         filter = new int[6] ;
411         filter[0] = 0 ;
412         filter[1] = 1 ;
413         filter[2] = 2 ;
414         filter[3] = 3 ;
415         filter[4] = 4 ;
416         filter[5] = 5 ;
417         break ;
418       }
419       case MED_HEXA8   : {
420         filter = new int[8] ;
421         filter[0] = 0 ;
422         filter[1] = 3 ;
423         filter[2] = 2 ;
424         filter[3] = 1 ;
425         filter[4] = 4 ;
426         filter[5] = 7 ;
427         filter[6] = 6 ;
428         filter[7] = 5 ;
429         break ;
430       }
431       case MED_TETRA10 : {
432         break ;
433       }
434       case MED_PYRA13  : {
435         break ;
436       }
437       case MED_PENTA15 : {
438         break ;
439       }
440       case MED_HEXA20  : {
441         break ;
442       }
443       default : { 
444         break ;
445       }
446       }
447     if (filter==NULL) 
448       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": MED element type not supported yet : " << cells_type[i].getName() ) ) ;
449     int nodes_cell = cells_type[i].getNumberOfNodes();
450     int numberOfCell = meshField->getNumberOfElements(MED_CELL,cells_type[i].getType()) ;
451     const int * connectivityArray = meshField->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,MED_CELL,cells_type[i].getType());
452     for (int j=0;j<numberOfCell;j++) {
453       (*_vtkFile) << nodes_cell << " " ;
454       for (int k=0;k<nodes_cell;k++)
455         (*_vtkFile) << connectivityArray[j*nodes_cell+filter[k]] - 1 << " " ;
456       (*_vtkFile) << endl ;
457     }
458     if (filter != NULL)
459       delete[] filter ;
460   }
461   (*_vtkFile) << endl ;
462   // we put cells type
463   (*_vtkFile) << "CELL_TYPES " << cells_sum << endl ;
464   for (int i=0;i<cells_types_count;i++) {
465     int vtkType = 0 ;
466     switch (cells_type[i].getType())
467       {
468       case MED_POINT1  : {
469         vtkType = 1 ;
470         break ;
471       }
472       case MED_SEG2    : {
473         vtkType = 3 ;
474         break ;
475       }
476       case MED_SEG3    : {  
477         vtkType = 0 ;
478         break ;
479       }
480       case MED_TRIA3   : {
481         vtkType = 5 ;
482         break ;
483       }
484       case MED_QUAD4   : {
485         vtkType = 9 ;
486         break ;
487       }
488       case MED_TRIA6   : {
489         vtkType = 0 ;
490         break ;
491       }
492       case MED_QUAD8   : {
493         vtkType = 0 ;
494         break ;
495       }
496       case MED_TETRA4  : {
497         vtkType = 10 ;
498         break ;
499       }
500       case MED_PYRA5   : {
501         vtkType = 14 ;
502         break ;
503       }
504       case MED_PENTA6  : {
505         vtkType = 13 ;
506         break ;
507       }
508       case MED_HEXA8   : {
509         vtkType = 12 ;
510         break ;
511       }
512       case MED_TETRA10 : {
513         vtkType = 0 ;
514         break ;
515       }
516       case MED_PYRA13  : {
517         vtkType = 0 ;
518         break ;
519       }
520       case MED_PENTA15 : {
521         vtkType = 0 ;
522         break ;
523       }
524       case MED_HEXA20  : {
525         vtkType = 0 ;
526         break ;
527       }
528       default : { 
529         vtkType = 0 ;
530         break ;
531       }
532       }
533     if (vtkType == 0)
534       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": MED element type not supported yet : " << cells_type[i].getType() ) ) ;
535     int numberOfCell = meshField->getNumberOfElements(MED_CELL,cells_type[i].getType()) ;
536     for (int j=0;j<numberOfCell;j++)
537       (*_vtkFile) << vtkType << endl ;
538   }
539
540   // first : field on node
541   // fields is on all node !
542
543   // second : field on cell
544   // fields is on all cell !
545
546   int dt = _ptrField->getIterationNumber();
547   int it = _ptrField->getOrderNumber();
548
549   ostringstream name ;
550   string nameField = _ptrField->getName();
551   medEntityMesh entitySupport = supportField->getEntity();
552   name << nameField << "_" << dt << "_" << it ;
553
554   if (!(supportField->isOnAllElements()))
555     throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<<_ptrField->getName()<<" which is not on all entities of the mesh !" << entitySupport));
556
557   if (entitySupport == MED_NODE)
558     (*_vtkFile) << "POINT_DATA " << meshField->getNumberOfNodes() << endl ;
559   else if (entitySupport == MED_CELL)
560     (*_vtkFile) << "CELL_DATA " << meshField->getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) << endl ;
561   else
562     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));
563
564   int NomberOfValue = supportField->getNumberOfElements(MED_ALL_ELEMENTS) ;
565   int NomberOfComponents =  _ptrField->getNumberOfComponents() ;
566
567   med_type_champ fieldType = _ptrField->getValueType() ;
568
569   SCRUTE(name.str());
570   SCRUTE(fieldType);
571
572   switch (fieldType)
573     {
574     case MED_INT32 :
575       {
576         break ;
577       }
578     case MED_REEL64 :
579       {
580         break ;
581       }
582     default :
583       { 
584         throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<< name.str() <<" the type is not int or double !"));
585       }
586     }
587
588   if (NomberOfComponents==3)
589     (*_vtkFile) << "VECTORS " << name.str() << " int" << endl ;
590   else if (NomberOfComponents<=4)
591     {
592       (*_vtkFile) << "SCALARS " << name.str() << " int " << NomberOfComponents << endl ;
593       (*_vtkFile) << "LOOKUP_TABLE default" << endl ;
594     }
595   else
596     throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<<_ptrField->getName()<<" there are more than 4 components !"));
597
598   const T * value = _ptrField->getValue(MED_NO_INTERLACE) ;
599
600   for (int i=0; i<NomberOfValue; i++)
601     {
602       for(int j=0; j<NomberOfComponents; j++)
603         (*_vtkFile) << value[j*NomberOfValue+i] << " " ;
604       (*_vtkFile) << endl ;
605     }
606   END_OF(LOC);
607 }
608
609 template <class T> void VTK_FIELD_DRIVER<T>::writeAppend(void) const
610   throw (MEDEXCEPTION)
611 {
612   const char * LOC = "VTK_FIELD_DRIVER::writeAppend(void) const " ;
613   BEGIN_OF(LOC);
614
615   // we get the Support and its associated Mesh
616
617   const SUPPORT * supportField = _ptrField->getSupport();
618   MESH * meshField = supportField->getMesh();
619
620   // Well we must open vtk file first, because there are
621   // no other driver than MED for VTK that do it !
622   openConstAppend() ;
623
624   // first : field on node
625   // fields is on all node !
626
627   // second : field on cell
628   // fields is on all cell !
629
630   int dt = _ptrField->getIterationNumber();
631   int it = _ptrField->getOrderNumber();
632
633   ostringstream name ;
634   string nameField = _ptrField->getName();
635   medEntityMesh entitySupport = supportField->getEntity();
636   name << nameField << "_" << dt << "_" << it ;
637
638   if (!(supportField->isOnAllElements()))
639     throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<<_ptrField->getName()<<" which is not on all entities of the mesh !" << entitySupport));
640
641   if (entitySupport == MED_NODE)
642     (*_vtkFile) << "POINT_DATA " << meshField->getNumberOfNodes() << endl ;
643   else if (entitySupport == MED_CELL)
644     (*_vtkFile) << "CELL_DATA " << meshField->getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) << endl ;
645   else
646     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));
647
648   int NomberOfValue = supportField->getNumberOfElements(MED_ALL_ELEMENTS) ;
649   int NomberOfComponents =  _ptrField->getNumberOfComponents() ;
650
651   med_type_champ fieldType = _ptrField->getValueType() ;
652
653   SCRUTE(name.str());
654   SCRUTE(fieldType);
655   switch (fieldType)
656     {
657     case MED_INT32 :
658       {
659         break ;
660       }
661     case MED_REEL64 :
662       {
663         break ;
664       }
665     default :
666       { 
667         throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<< name.str() <<" the type is not int or double !"));
668       }
669     }
670
671   if (NomberOfComponents==3)
672     (*_vtkFile) << "VECTORS " << name.str() << " int" << endl ;
673   else if (NomberOfComponents<=4)
674     {
675       (*_vtkFile) << "SCALARS " << name.str() << " int " << NomberOfComponents << endl ;
676       (*_vtkFile) << "LOOKUP_TABLE default" << endl ;
677     }
678   else
679     throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<<_ptrField->getName()<<" there are more than 4 components !"));
680
681   const T * value = _ptrField->getValue(MED_NO_INTERLACE) ;
682
683   for (int i=0; i<NomberOfValue; i++)
684     {
685       for(int j=0; j<NomberOfComponents; j++)
686         (*_vtkFile) << value[j*NomberOfValue+i] << " " ;
687       (*_vtkFile) << endl ;
688     }
689   END_OF(LOC);
690 }
691
692 #endif /* VTK_FIELD_DRIVER_HXX */