Salome HOME
merging the main trunk with the BrForComp branch to build a pre V3_0_1
[modules/med.git] / src / MEDMEM / MEDMEM_VtkMeshDriver.cxx
1 #include "MEDMEM_VtkMeshDriver.hxx"
2
3 #include "MEDMEM_DriversDef.hxx"
4
5 #include "MEDMEM_Family.hxx"
6 #include "MEDMEM_Group.hxx"
7 #include "MEDMEM_Coordinate.hxx"
8 #include "MEDMEM_Connectivity.hxx"
9 #include "MEDMEM_Mesh.hxx"
10 #include "MEDMEM_CellModel.hxx"
11 #include "MEDMEM_Grid.hxx"
12
13 #include <sstream>
14
15 using namespace std;
16 using namespace MEDMEM;
17 using namespace MED_EN;
18
19 #define MED_NULL     NULL
20
21 VTK_MESH_DRIVER::VTK_MESH_DRIVER(): GENDRIVER(), 
22                                     _ptrMesh((MESH * const)MED_NULL)
23 {
24   _vtkFile = new ofstream();
25   // What about _id in Gendriver ?
26   // _driverType ???
27 }
28
29 VTK_MESH_DRIVER::VTK_MESH_DRIVER(const string & fileName,
30                                  MESH * ptrMesh) :
31   GENDRIVER(fileName,MED_WRONLY),
32   _ptrMesh(ptrMesh)
33 {
34   const char * LOC = "VTK_MESH_DRIVER::VTK_MESH_DRIVER(const string & fileName, MESH * ptrMesh) : " ;
35
36   // Send an exception because a VTK_MESH_DRIVER object cannot be instantied
37   // from a file and there is no read for that kind of driver
38
39   //  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!"));
40
41   //  _ptrMesh->addDriver(*this); // OU RECUPERER L'ID.
42   MESSAGE(LOC << "WARNING this driver is only used to write in VTK format So the object can not be instantied using a file!");
43
44   _vtkFile = new ofstream(); 
45 }
46
47 VTK_MESH_DRIVER::VTK_MESH_DRIVER(const VTK_MESH_DRIVER & driver): 
48   GENDRIVER(driver),
49   _ptrMesh(driver._ptrMesh),
50   _meshName(driver._meshName)
51 {
52   _ptrMesh->addDriver(*this);
53   _vtkFile = new ofstream();
54 }
55
56 VTK_MESH_DRIVER::~VTK_MESH_DRIVER()
57 {
58   const char * LOC ="VTK_MESH_DRIVER::~VTK_MESH_DRIVER()";
59   BEGIN_OF(LOC);
60
61   close();
62
63   SCRUTE(_vtkFile);
64
65   delete _vtkFile ;
66
67   SCRUTE(_vtkFile);
68
69   END_OF(LOC);
70 }
71
72 void VTK_MESH_DRIVER::openConst() const throw (MEDEXCEPTION)
73 {
74   const char * LOC = "VTK_MESH_DRIVER::openConst()" ;
75   BEGIN_OF(LOC);
76
77   MESSAGE(LOC<<" : _fileName.c_str : "<< _fileName.c_str()<<",mode : "<< _accessMode);
78
79   if ( _fileName == "" )
80     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
81                                      << "_fileName is |\"\"|, please set a correct fileName before calling open()"
82                                      )
83                           );
84
85   if (!(*_vtkFile).is_open())
86     (*_vtkFile).open(_fileName.c_str()) ; 
87 //    if (*_vtkFile)
88 //      _status = MED_OPENED ;
89 //    else
90
91
92   SCRUTE((*_vtkFile).is_open());
93   SCRUTE(_vtkFile);
94
95
96
97   if (!(*_vtkFile))
98     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not open file "
99                                      << _fileName)
100                           );
101   END_OF(LOC);
102 }
103
104 void VTK_MESH_DRIVER::open() {
105   openConst() ;
106 }
107
108 void VTK_MESH_DRIVER::closeConst() const throw (MEDEXCEPTION)
109 {
110   const char * LOC = "VTK_MESH_DRIVER::closeConst() " ;
111   BEGIN_OF(LOC);
112
113   SCRUTE(_vtkFile);
114   SCRUTE(*_vtkFile);
115
116
117   if ((*_vtkFile).is_open())
118     (*_vtkFile).close();
119   
120 //    if (*_vtkFile)
121 //      _status = MED_CLOSED ;
122 //    else
123
124   SCRUTE(_vtkFile);
125   SCRUTE(*_vtkFile);
126
127   if (!(*_vtkFile))
128     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not close file "
129                                      << _fileName)
130                           );
131
132   END_OF(LOC);
133 }
134
135 void VTK_MESH_DRIVER::close() {
136   closeConst() ;
137 }
138
139 void    VTK_MESH_DRIVER::setMeshName(const string & meshName) { _meshName = meshName; };
140 string  VTK_MESH_DRIVER::getMeshName() const { return _meshName; };
141
142 void VTK_MESH_DRIVER::read(void) throw (MEDEXCEPTION)
143 {
144   const char * LOC = "VTK_MESH_DRIVER::read() : " ;
145   BEGIN_OF(LOC);
146
147   // Send an exception
148
149   throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "This driver is only used to write in VTK format !"));
150
151   END_OF(LOC);
152 }
153
154
155 void VTK_MESH_DRIVER::write(void) const
156   throw (MEDEXCEPTION)
157
158   const char * LOC = "void VTK_MESH_DRIVER::write(void) const : ";
159   BEGIN_OF(LOC);
160
161   // Well we must open vtk file first, because there are
162   // no other driver than MED for VTK that do it !
163
164   openConst();
165
166   (*_vtkFile) << "# vtk DataFile Version 2.0" << endl 
167            << "maillage from MedMemory"  << endl ;
168   // only ASCII for the moment (binary came later :-)
169   (*_vtkFile) << "ASCII" << endl ;
170
171
172   (*_vtkFile) << "DATASET UNSTRUCTURED_GRID" << endl ;
173   // put points (all point are in 3D, so if we are in 1D or 2D, we complete by zero !
174   int SpaceDimension = _ptrMesh->getSpaceDimension() ;
175   int NumberOfNodes = _ptrMesh->getNumberOfNodes() ;
176   (*_vtkFile) << "POINTS " << NumberOfNodes << " float" << endl ;
177   const double *coordinate = _ptrMesh->getCoordinates(MED_FULL_INTERLACE) ;
178   for (int i=0;i<NumberOfNodes;i++) {
179     for (int j=0;j<SpaceDimension;j++)
180       (*_vtkFile) << coordinate[i*SpaceDimension+j] << " " ;
181     if (SpaceDimension==1) 
182       (*_vtkFile) << "0 0" ;
183     if (SpaceDimension==2) 
184       (*_vtkFile) << "0" ;
185     (*_vtkFile) << endl ;
186   }
187
188   // we put connectivity
189   // how many cells and how many value in connectivity :
190   int cells_types_count = _ptrMesh->getNumberOfTypes(MED_CELL) ;
191   //  int * cells_count = _ptrMesh->get_cells_count() ;
192   //  int cells_sum = cells_count[cells_types_count] ;
193   int cells_sum = _ptrMesh->getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) ;
194   const CELLMODEL * cells_type = _ptrMesh->getCellsTypes(MED_CELL) ;
195   //  int connectivity_sum = 0 ;
196
197   //const int * connectivity = _ptrMesh->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,MED_CELL,MED_ALL_ELEMENTS) ; !! UNUSED VARIABLE !!
198   const int * connectivityIndex = _ptrMesh->getConnectivityIndex(MED_NODAL,MED_CELL) ;
199
200   int connectivity_sum =  connectivityIndex[cells_sum]-1 ;
201
202   (*_vtkFile) << "CELLS " << cells_sum << " " << connectivity_sum+cells_sum << endl ;
203   // we put connectivity
204   for (int i=0;i<cells_types_count;i++) {
205     int *filter = (int*) NULL ; // index in vtk connectivity
206     switch (cells_type[i].getType())
207       {
208       case MED_POINT1  : {
209         filter = new int[1] ;
210         filter[0] = 0 ;
211         break ;
212       }
213       case MED_SEG2    : {
214         filter = new int[2] ;
215         filter[0] = 0 ;
216         filter[1] = 1 ;
217         break ;
218       }
219       case MED_SEG3    : {  
220         break ;
221       }
222       case MED_TRIA3   : {
223         filter = new int[3] ;
224         filter[0] = 0 ;
225         filter[1] = 1 ;
226         filter[2] = 2 ;
227         break ;
228       }
229       case MED_QUAD4   : {
230         filter = new int[4] ;
231         filter[0] = 0 ;
232         filter[1] = 1 ;
233         filter[2] = 2 ;
234         filter[3] = 3 ;
235         break ;
236       }
237       case MED_TRIA6   : {
238         break ;
239       }
240       case MED_QUAD8   : {
241         break ;
242       }
243       case MED_TETRA4  : {
244         filter = new int[4] ;
245         filter[0] = 0 ;
246         filter[1] = 1 ;
247         filter[2] = 3 ;  // 3td element in med are 4th in vtk (array begin at 0 !)
248         filter[3] = 2 ;  // 4th element in med are 3rd in vtk (array begin at 0 !)
249         break ;
250       }
251       case MED_PYRA5   : {
252         filter = new int[5] ;
253         filter[0] = 0 ;
254         filter[1] = 3 ;  // 2nd element in med are 4th in vtk (array begin at 0 !)
255         filter[2] = 2 ;
256         filter[3] = 1 ;  // 4th element in med are 2nd in vtk (array begin at 0 !)
257         filter[4] = 4 ;
258         break ;
259       }
260       case MED_PENTA6  : {
261         filter = new int[6] ;
262         filter[0] = 0 ;
263         filter[1] = 1 ;
264         filter[2] = 2 ;
265         filter[3] = 3 ;
266         filter[4] = 4 ;
267         filter[5] = 5 ;
268         break ;
269       }
270       case MED_HEXA8   : {
271         filter = new int[8] ;
272         filter[0] = 0 ;
273         filter[1] = 3 ;
274         filter[2] = 2 ;
275         filter[3] = 1 ;
276         filter[4] = 4 ;
277         filter[5] = 7 ;
278         filter[6] = 6 ;
279         filter[7] = 5 ;
280         break ;
281       }
282       case MED_TETRA10 : {
283         break ;
284       }
285       case MED_PYRA13  : {
286         break ;
287       }
288       case MED_PENTA15 : {
289         break ;
290       }
291       case MED_HEXA20  : {
292         break ;
293       }
294       default : { 
295         break ;
296       }
297       }
298     if (filter==NULL) 
299       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": MED element type not supported yet : " << cells_type[i].getName() ) ) ;
300     int nodes_cell = cells_type[i].getNumberOfNodes();
301     int numberOfCell = _ptrMesh->getNumberOfElements(MED_CELL,cells_type[i].getType()) ;
302     const int * connectivityArray = _ptrMesh->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,MED_CELL,cells_type[i].getType());
303     for (int j=0;j<numberOfCell;j++) {
304       (*_vtkFile) << nodes_cell << " " ;
305       for (int k=0;k<nodes_cell;k++)
306         (*_vtkFile) << connectivityArray[j*nodes_cell+filter[k]] - 1 << " " ;
307       (*_vtkFile) << endl ;
308     }
309     if (filter != NULL)
310       delete[] filter ;
311   }
312   (*_vtkFile) << endl ;
313   // we put cells type
314   (*_vtkFile) << "CELL_TYPES " << cells_sum << endl ;
315   for (int i=0;i<cells_types_count;i++) {
316     int vtkType = 0 ;
317     switch (cells_type[i].getType())
318       {
319       case MED_POINT1  : {
320         vtkType = 1 ;
321         break ;
322       }
323       case MED_SEG2    : {
324         vtkType = 3 ;
325         break ;
326       }
327       case MED_SEG3    : {  
328         vtkType = 0 ;
329         break ;
330       }
331       case MED_TRIA3   : {
332         vtkType = 5 ;
333         break ;
334       }
335       case MED_QUAD4   : {
336         vtkType = 9 ;
337         break ;
338       }
339       case MED_TRIA6   : {
340         vtkType = 0 ;
341         break ;
342       }
343       case MED_QUAD8   : {
344         vtkType = 0 ;
345         break ;
346       }
347       case MED_TETRA4  : {
348         vtkType = 10 ;
349         break ;
350       }
351       case MED_PYRA5   : {
352         vtkType = 14 ;
353         break ;
354       }
355       case MED_PENTA6  : {
356         vtkType = 13 ;
357         break ;
358       }
359       case MED_HEXA8   : {
360         vtkType = 12 ;
361         break ;
362       }
363       case MED_TETRA10 : {
364         vtkType = 0 ;
365         break ;
366       }
367       case MED_PYRA13  : {
368         vtkType = 0 ;
369         break ;
370       }
371       case MED_PENTA15 : {
372         vtkType = 0 ;
373         break ;
374       }
375       case MED_HEXA20  : {
376         vtkType = 0 ;
377         break ;
378       }
379       default : { 
380         vtkType = 0 ;
381         break ;
382       }
383       }
384     if (vtkType == 0)
385       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": MED element type not supported yet : " << cells_type[i].getType() ) ) ;
386     int numberOfCell = _ptrMesh->getNumberOfElements(MED_CELL,cells_type[i].getType()) ;
387     for (int j=0;j<numberOfCell;j++)
388       (*_vtkFile) << vtkType << endl ;
389   }
390
391
392   END_OF(LOC);
393
394
395 GENDRIVER * VTK_MESH_DRIVER::copy(void) const
396 {
397   return new VTK_MESH_DRIVER(*this);
398 }