1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/
20 #include "MEDMEM_VtkMedDriver.hxx"
24 #include "MEDMEM_define.hxx"
25 #include "MEDMEM_Med.hxx"
26 #include "MEDMEM_Field.hxx"
27 #include "MEDMEM_Support.hxx"
28 #include "MEDMEM_Mesh.hxx"
29 #include "MEDMEM_CellModel.hxx"
32 using namespace MEDMEM;
33 using namespace MED_EN;
35 VTK_MED_DRIVER::VTK_MED_DRIVER(): GENDRIVER(),
36 _ptrMed((MED * const)MED_NULL)
38 _vtkFile = new ofstream();
39 // What about _id in Gendriver ?
44 VTK_MED_DRIVER::VTK_MED_DRIVER(const string & fileName, MED * const ptrMed):
45 GENDRIVER(fileName,MED_EN::MED_RDWR), _ptrMed(ptrMed)
47 _vtkFile = new ofstream();
50 VTK_MED_DRIVER::VTK_MED_DRIVER(const VTK_MED_DRIVER & driver):
52 _ptrMed(driver._ptrMed)
54 _ptrMed->addDriver(*this); // OU RECUPERER L'ID.
55 _vtkFile = new ofstream();
56 // What about _id in Gendriver ?
60 VTK_MED_DRIVER::~VTK_MED_DRIVER()
62 const char * LOC ="VTK_MED_DRIVER::~VTK_MED_DRIVER()";
71 GENDRIVER * VTK_MED_DRIVER::copy() const
73 return new VTK_MED_DRIVER(*this) ;
76 //REM : As t'on besoin du champ _status : _vtkFile <-> _status ? Oui
78 void VTK_MED_DRIVER::openConst() const {
80 const char * LOC ="VTK_MED_DRIVER::open() : ";
83 if ( _fileName == "" )
84 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
85 << "_fileName is |\"\"|, please set a correct fileName before calling open()"
89 if (!(*_vtkFile).is_open())
90 (*_vtkFile).open(_fileName.c_str()) ;
92 // _status = MED_OPENED ;
95 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not open file "
101 void VTK_MED_DRIVER::open() {
105 void VTK_MED_DRIVER::closeConst() const {
107 const char * LOC = "VTK_MED_DRIVER::close() : ";
113 // _status = MED_CLOSED ;
116 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not close file "
122 void VTK_MED_DRIVER::close() {
127 void VTK_MED_DRIVER::write() const {
129 const char * LOC = "VTK_MED_DRIVER::write() : ";
132 // Well we must open vtk file first, because there are
133 // no other driver than MED for VTK that do it !
136 // could we put more than one Mesh ?????
137 (*_vtkFile) << "# vtk DataFile Version 2.0" << endl
138 << "maillage from MedMemory" << endl ;
139 // only ASCII for the moment (binary came later :-)
140 (*_vtkFile) << "ASCII" << endl ;
142 int NumberOfMeshes = _ptrMed->getNumberOfMeshes() ;
143 deque<string> MeshNames = _ptrMed->getMeshNames() ;
144 //deque<string>::const_iterator currentMesh ; !! UNUSED VARIABLE !!
145 // In fact, we must take care of all supports
146 // We restrict Field on all nodes or cells
148 int NumberOfFields = _ptrMed->getNumberOfFields() ;
149 deque<string> FieldNames = _ptrMed->getFieldNames() ;
150 //deque<string>::const_iterator currentField ; !! UNUSED VARIABLE !!
152 // for ( currentMesh=MeshName.begin();currentMesh != MeshName.end(); currentMesh++) {
153 for (int i=0; i<NumberOfMeshes; i++) {
154 MESH * myMesh = _ptrMed->getMesh(MeshNames[i]) ;
156 // get all field which values are on this mesh => revoir api de Med !!!
157 // first : field on node
158 // fields is on all node !
159 (*_vtkFile) << "POINT_DATA " << myMesh->getNumberOfNodes() << endl ;
160 for (int j=0; j<NumberOfFields; j++) {
161 deque<DT_IT_> timeStep = _ptrMed->getFieldIteration(FieldNames[j]) ;
162 deque<DT_IT_>::const_iterator currentTimeStep ;
163 for ( currentTimeStep=timeStep.begin(); currentTimeStep!=timeStep.end(); currentTimeStep++) {
164 int dt = (*currentTimeStep).dt ;
165 int it = (*currentTimeStep).it ;
166 FIELD_ * myField = _ptrMed->getField(FieldNames[j],dt,it) ;
167 if( MeshNames[i] == myField->getSupport()->getMesh()->getName() ) {
168 // rigth in all case : better compare pointeur ?
169 if (MED_NODE == myField->getSupport()->getEntity())
170 if (myField->getSupport()->isOnAllElements()) {
172 name << myField->getName() << "_" << dt << "_" << it ;
173 writeField(myField,name.str()) ;
175 MESSAGE(LOC << "Could not write field "<<myField->getName()<<" which is not on all nodes !");
180 (*_vtkFile) << "CELL_DATA " << myMesh->getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) << endl ;
181 // second : field on cell
182 for (int j=0; j<NumberOfFields; j++) {
183 deque<DT_IT_> timeStep = _ptrMed->getFieldIteration(FieldNames[j]) ;
184 deque<DT_IT_>::const_iterator currentTimeStep ;
185 for ( currentTimeStep=timeStep.begin(); currentTimeStep!=timeStep.end(); currentTimeStep++) {
186 int dt = (*currentTimeStep).dt;
187 int it = (*currentTimeStep).it;
188 FIELD_ * myField = _ptrMed->getField(FieldNames[j],dt,it) ;
189 if( MeshNames[i] == myField->getSupport()->getMesh()->getName() ) {
190 // rigth in all case : better compare pointeur ?
191 if (MED_CELL == myField->getSupport()->getEntity())
192 if (myField->getSupport()->isOnAllElements()) {
194 name << myField->getName() << "_" << dt << "_" << it ;
195 writeField(myField,name.str()) ;
197 MESSAGE(LOC << "Could not write field "<<myField->getName()<<" which is not on all cells !");
204 // Well we must close vtk file first, because there are
205 // no other driver than MED for VTK that do it !
211 void VTK_MED_DRIVER::writeMesh(MESH * myMesh) const {
213 const char * LOC = "VTK_MED_DRIVER::writeMesh() : ";
216 (*_vtkFile) << "DATASET UNSTRUCTURED_GRID" << endl ;
217 // put points (all point are in 3D, so if we are in 1D or 2D, we complete by zero !
218 int SpaceDimension = myMesh->getSpaceDimension() ;
219 int NumberOfNodes = myMesh->getNumberOfNodes() ;
220 (*_vtkFile) << "POINTS " << NumberOfNodes << " float" << endl ;
221 const double *coordinate = myMesh->getCoordinates(MED_FULL_INTERLACE) ;
222 for (int i=0;i<NumberOfNodes;i++) {
223 for (int j=0;j<SpaceDimension;j++)
224 (*_vtkFile) << coordinate[i*SpaceDimension+j] << " " ;
225 if (SpaceDimension==1)
226 (*_vtkFile) << "0 0" ;
227 if (SpaceDimension==2)
229 (*_vtkFile) << endl ;
232 // we put connectivity
233 // how many cells and how many value in connectivity :
234 int cells_types_count = myMesh->getNumberOfTypes(MED_CELL) ;
235 // int * cells_count = myMesh->get_cells_count() ;
236 // int cells_sum = cells_count[cells_types_count] ;
237 int cells_sum = myMesh->getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) ;
238 const CELLMODEL * cells_type = myMesh->getCellsTypes(MED_CELL) ;
239 // int connectivity_sum = 0 ;
241 //const int * connectivity = myMesh->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,MED_CELL,MED_ALL_ELEMENTS) ; !! UNUSED VARIABLE !!
242 const int * connectivityIndex = myMesh->getConnectivityIndex(MED_NODAL,MED_CELL) ;
244 int connectivity_sum = connectivityIndex[cells_sum]-1 ;
246 (*_vtkFile) << "CELLS " << cells_sum << " " << connectivity_sum+cells_sum << endl ;
247 // we put connectivity
248 for (int i=0;i<cells_types_count;i++) {
249 int *filter = (int*) NULL ; // index in vtk connectivity
250 switch (cells_type[i].getType())
253 filter = new int[1] ;
258 filter = new int[2] ;
267 filter = new int[3] ;
274 filter = new int[4] ;
288 filter = new int[4] ;
291 filter[2] = 3 ; // 3td element in med are 4th in vtk (array begin at 0 !)
292 filter[3] = 2 ; // 4th element in med are 3rd in vtk (array begin at 0 !)
296 filter = new int[5] ;
298 filter[1] = 3 ; // 2nd element in med are 4th in vtk (array begin at 0 !)
300 filter[3] = 1 ; // 4th element in med are 2nd in vtk (array begin at 0 !)
305 filter = new int[6] ;
315 filter = new int[8] ;
343 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": MED element type not supported yet : " << cells_type[i].getName() ) ) ;
344 int nodes_cell = cells_type[i].getNumberOfNodes();
345 int numberOfCell = myMesh->getNumberOfElements(MED_CELL,cells_type[i].getType()) ;
346 const int * connectivityArray = myMesh->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,MED_CELL,cells_type[i].getType());
347 for (int j=0;j<numberOfCell;j++) {
348 (*_vtkFile) << nodes_cell << " " ;
349 for (int k=0;k<nodes_cell;k++)
350 (*_vtkFile) << connectivityArray[j*nodes_cell+filter[k]] - 1 << " " ;
351 (*_vtkFile) << endl ;
356 (*_vtkFile) << endl ;
358 (*_vtkFile) << "CELL_TYPES " << cells_sum << endl ;
359 for (int i=0;i<cells_types_count;i++) {
361 switch (cells_type[i].getType())
429 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": MED element type not supported yet : " << cells_type[i].getType() ) ) ;
430 int numberOfCell = myMesh->getNumberOfElements(MED_CELL,cells_type[i].getType()) ;
431 for (int j=0;j<numberOfCell;j++)
432 (*_vtkFile) << vtkType << endl ;
435 // add a constant field on all node to test !
436 // _vtkFile << "POINT_DATA " << NumberOfNodes << endl ;
437 // _vtkFile << "SCALARS example_scalaire float 1" << endl ;
438 // _vtkFile << "LOOKUP_TABLE default" << endl ;
439 // for (int i=0;i<NumberOfNodes;i++)
440 // _vtkFile << i << endl ;
448 void VTK_MED_DRIVER::writeField(FIELD_ * myField,string name) const {
450 const char * LOC = "VTK_MED_DRIVER::writeField() : ";
453 int NomberOfValue = myField->getSupport()->getNumberOfElements(MED_ALL_ELEMENTS) ;
454 int NomberOfComponents = myField->getNumberOfComponents() ;
456 med_type_champ type = myField->getValueType() ;
462 MESSAGE("MED_INT32");
463 if (NomberOfComponents==3) {
464 (*_vtkFile) << "VECTORS " << name << " int" << endl ;
465 } else if (NomberOfComponents<=4) {
466 (*_vtkFile) << "SCALARS " << name << " int " << NomberOfComponents << endl ;
467 (*_vtkFile) << "LOOKUP_TABLE default" << endl ;
469 MESSAGE(LOC << "Could not write field "<<myField->getName()<<" there are more than 4 components !");
473 //const int * value = ((FIELD<int>*)myField)->getValue(MED_NO_INTERLACE) ;
474 const int * value = ((FIELD<int>*)myField)->getValue(MED_NO_INTERLACE) ;
475 for (int i=0; i<NomberOfValue; i++) {
476 for(int j=0; j<NomberOfComponents; j++)
477 (*_vtkFile) << value[j*NomberOfValue+i] << " " ;
478 (*_vtkFile) << endl ;
483 MESSAGE("MED_REEL64");
484 if (NomberOfComponents==3) {
485 (*_vtkFile) << "VECTORS " << name << " float" << endl ;
486 } else if (NomberOfComponents<=4) {
487 (*_vtkFile) << "SCALARS " << name << " float " << NomberOfComponents << endl ;
488 (*_vtkFile) << "LOOKUP_TABLE default" << endl ;
490 MESSAGE(LOC << "Could not write field "<<myField->getName()<<" there are more than 4 components !");
493 const double * value = ((FIELD<double>*)myField)->getValue(MED_NO_INTERLACE) ;
494 for (int i=0; i<NomberOfValue; i++) {
495 for(int j=0; j<NomberOfComponents; j++)
496 (*_vtkFile) << value[j*NomberOfValue+i] << " " ;
497 (*_vtkFile) << endl ;
502 MESSAGE(LOC << "Could not write field "<<name<<" the type is not int or double !");
509 void VTK_MED_DRIVER::writeSupport(SUPPORT * mySupport) const {
510 const char * LOC = "VTK_MED_DRIVER::writeSupport(SUPPORT *) : " ;
512 MESSAGE(LOC << "Not yet implemented, acting on the object " << *mySupport);