]> SALOME platform Git repositories - modules/visu.git/blob - src/VISU_I/VISU_Convertor_impl.cxx
Salome HOME
NRI : Merge from V1_2.
[modules/visu.git] / src / VISU_I / VISU_Convertor_impl.cxx
1 //  Copyright (C) 2003  CEA/DEN, EDF R&D
2 //
3 //
4 //
5 //  File   : VISU_Convertor_impl.cxx
6 //  Author : Alexey PETROV
7 //  Module : VISU
8
9 using namespace std;
10 #include "VISU_Convertor_impl.hxx"
11
12 #include <vtkUnstructuredGridReader.h>
13 #include <qstring.h>
14 #include <qfileinfo.h>
15 #include <vtkCellType.h>
16 #include <valarray>     
17 #include <memory>
18 using namespace std;
19
20 #ifdef DEBUG
21 static int MYDEBUG = 0;
22 static int MYDEBUGWITHFILES = 0;
23 #else
24 static int MYDEBUG = 0;
25 static int MYDEBUGWITHFILES = 0;
26 #endif
27 static int PRECISION = 7;
28
29 #define MED2VTK(MEDTYPE,VTKTYPE,VTKNBNODES) \
30  {MEDTYPE,#MEDTYPE,getNbMedNodes(MEDTYPE),VTKTYPE,#VTKTYPE,VTKNBNODES}
31 Med2vtk med2vtk[MED_NBR_GEOMETRIE_MAILLE] = {
32   MED2VTK(MED_POINT1,VTK_VERTEX,1),
33   MED2VTK(MED_SEG2,VTK_LINE,2),
34   MED2VTK(MED_SEG3,VTK_LINE,2),
35   MED2VTK(MED_TRIA3,VTK_TRIANGLE,3),
36   MED2VTK(MED_TRIA6,VTK_TRIANGLE,3),
37   MED2VTK(MED_QUAD4,VTK_QUAD,4),
38   MED2VTK(MED_QUAD8,VTK_QUAD,4),
39   MED2VTK(MED_TETRA4,VTK_TETRA,4),
40   MED2VTK(MED_TETRA10,VTK_TETRA,4),
41   MED2VTK(MED_HEXA8,VTK_HEXAHEDRON,8),
42   MED2VTK(MED_HEXA20,VTK_HEXAHEDRON,8),
43   MED2VTK(MED_PENTA6,VTK_WEDGE,6),
44   MED2VTK(MED_PENTA15,VTK_WEDGE,6),
45   MED2VTK(MED_PYRA5,VTK_PYRAMID,5),
46   MED2VTK(MED_PYRA13,VTK_PYRAMID,5)
47 };
48 #undef MED2VTK
49
50 extern "C" {
51   VISU_Convertor* CreateConvertor(const string& theFileName) throw(std::runtime_error&){
52     if(QFileInfo(theFileName.c_str()).extension(false) == "med")
53       return CreateMedConvertor(theFileName);
54     else
55       return CreateDatConvertor(theFileName);
56   }
57
58   int getNbMedConnect(int theMedType, int theMedEntity, int theMeshDim){
59     int anElemDim = theMedType / 100, nsup = 0;
60     if(theMedEntity == VISU::CELL_ENTITY && anElemDim < theMeshDim) nsup = 1;
61     return nsup + theMedType % 100;
62   }
63
64   int getNbMedNodes(int geom){ 
65     return geom % 100;
66   } 
67
68   int getIdMedType(int medType){
69     for(int i = 0; i < MED_NBR_GEOMETRIE_MAILLE; i++)
70       if(med2vtk[i].medType == medType) return i;
71     return -1;
72   }
73 }
74
75 VISU_Convertor_impl::VISU_Convertor_impl() {
76   myIsDone = false;
77 }
78
79 VISU_Convertor_impl::~VISU_Convertor_impl() {}
80
81 VISU_Convertor::OutputType* VISU_Convertor_impl::GetMeshOnEntity(const string& theMeshName, 
82                                                                  const VISU::TEntity& theEntity,
83                                                                  const string& theFamilyName)
84   throw (std::runtime_error&)
85 {
86   if(!myIsDone) { myIsDone = true;  Build();}
87   if(MYDEBUG) 
88     MESSAGE("GetMeshOnEntity - theMeshName = '"<<theMeshName<<
89             "'; theEntity = "<<theEntity<<"; theFamilyName = '"<<theFamilyName<<"'");
90   //Cheching possibility do the query
91   if(myMeshMap.find(theMeshName) == myMeshMap.end())
92     throw std::runtime_error("MeshOnEntityToString >> There is no mesh with the name!!!");
93   VISU::TMesh& aMesh = myMeshMap[theMeshName];
94   VISU::TMeshOnEntityMap& aMeshOnEntityMap = aMesh.myMeshOnEntityMap;
95   if(aMeshOnEntityMap.find(theEntity) == aMeshOnEntityMap.end())
96     throw std::runtime_error("MeshOnEntityToString >> There is no mesh on the entity!!!");
97   VISU::TMeshOnEntity& aMeshOnEntity = aMeshOnEntityMap[theEntity];
98   VISU::TFamily* pFamily = VISU::GetFamily(aMeshOnEntity,theFamilyName);
99   VISU::TVTKReader* pReader;
100   if(pFamily != NULL)
101     pReader = &(pFamily->myStorage);
102   else
103     pReader = &(aMeshOnEntity.myStorage);
104   VISU::TVTKReader& aReader = *pReader;
105   //Main part of code
106   if(aReader.get() == NULL){
107     LoadMeshOnEntity(aMeshOnEntity,theFamilyName);
108     ostrstream strOut;
109     strOut<<GetHead(theMeshName + dtos("-%d-",theEntity) + theFamilyName);
110     strOut<<GetPoints(aMesh);
111     pair<int,int> aCellsDim = aMeshOnEntity.GetCellsDims(theFamilyName);
112     int aNbCells = aCellsDim.first, aCellsSize = aCellsDim.second;
113     ostrstream strCellsOut, strTypesOut;
114     GetCells(strCellsOut,strTypesOut,aMeshOnEntity,theFamilyName);
115     strCellsOut<<ends;
116     strTypesOut<<ends;
117     strOut<<"CELLS "<<aNbCells<<"\t"<<aCellsSize<<endl;
118     auto_ptr<char> aRet(strCellsOut.str());
119     strOut<<aRet.get()<<endl;
120     strOut<<"CELL_TYPES "<<aNbCells<<endl;
121     aRet.reset(strTypesOut.str());
122     strOut<<aRet.get()<<endl;
123     strOut<<ends;
124     aReader.reset(OutputType::New());
125     //aReader = OutputType::New();
126     //aReader->DebugOn();
127     aReader->ReadFromInputStringOn();
128     aRet.reset(strOut.str());
129     aReader->SetInputString(aRet.get());
130     //aReader->Update();
131     //aReader->Print(cout);
132     if(MYDEBUGWITHFILES){
133       string aMeshName = QString(theMeshName.c_str()).simplifyWhiteSpace().latin1();
134       string aFamilyName = QString(theFamilyName.c_str()).simplifyWhiteSpace().latin1();
135       string aFileName = string("/users/")+getenv("USER")+"/"+getenv("USER")+"-";
136       aFileName += aMeshName + dtos("-%d-",theEntity) + aFamilyName + "-Conv.vtk";
137       ofstream stmOut(aFileName.c_str(),ios::out);
138       stmOut<<aRet.get();
139     }
140   }
141   return aReader.get();
142   //return aReader;
143 }
144
145 VISU_Convertor::OutputType* VISU_Convertor_impl::GetMeshOnGroup(const string& theMeshName, 
146                                                                 const string& theGroupName)
147      throw(std::runtime_error&)
148 {
149   if(!myIsDone) { myIsDone = true;  Build();}
150   if(MYDEBUG) MESSAGE("GetMeshOnGroup - theMeshName = '"<<theMeshName<<
151                       "'; theGroupName = '"<<theGroupName<<"'");
152   //Cheching possibility do the query
153   if(myMeshMap.find(theMeshName) == myMeshMap.end())
154     throw std::runtime_error("GetMeshOnGroup >> There is no mesh with the name!!!");
155   VISU::TMesh& aMesh = myMeshMap[theMeshName];
156   VISU::TGroupMap& aGroupMap = aMesh.myGroupMap;
157   VISU::TGroupMap::iterator aGroupMapIter = aGroupMap.find(theGroupName);
158   if(aGroupMapIter == aGroupMap.end())
159     throw std::runtime_error("GetMeshOnGroup >> There is no the group in the mesh!!!");
160   VISU::TGroup& aGroup = aGroupMapIter->second;
161   const VISU::TFamilyAndEntitySet& aFamilyAndEntitySet = aGroup.myFamilyAndEntitySet;
162   VISU::TVTKReader& aReader = aGroup.myStorage;
163   if(aReader.get() == NULL){
164     LoadMeshOnGroup(aMesh,aFamilyAndEntitySet);
165     ostrstream strOut;
166     strOut<<GetHead(theMeshName + "-" + theGroupName);
167     strOut<<GetPoints(aMesh);
168     VISU::TFamilyAndEntitySet::const_iterator aFamilyAndEntitySetIter = aFamilyAndEntitySet.begin();
169     int aNbCells = 0, aCellsSize = 0;
170     ostrstream strCellsOut, strTypesOut;
171     for(; aFamilyAndEntitySetIter != aFamilyAndEntitySet.end(); aFamilyAndEntitySetIter++){
172       const VISU::TFamilyAndEntity& aFamilyAndEntity = *aFamilyAndEntitySetIter;
173       const string& aFamilyName = aFamilyAndEntity.first;
174       const VISU::TEntity& anEntity = aFamilyAndEntity.second;
175       VISU::TMeshOnEntity& aMeshOnEntity = aMesh.myMeshOnEntityMap[anEntity];
176       pair<int,int> aCellsDim = aMeshOnEntity.GetCellsDims(aFamilyName);
177       aNbCells += aCellsDim.first;
178       aCellsSize += aCellsDim.second;
179       GetCells(strCellsOut,strTypesOut,aMeshOnEntity,aFamilyName);
180     }
181     strCellsOut<<ends;
182     strTypesOut<<ends;
183     strOut<<"CELLS "<<aNbCells<<"\t"<<aCellsSize<<endl;
184     auto_ptr<char> aRet(strCellsOut.str());
185     strOut<<aRet.get()<<endl;
186     strOut<<"CELL_TYPES "<<aNbCells<<endl;
187     aRet.reset(strTypesOut.str());
188     strOut<<aRet.get()<<endl;
189     strOut<<ends;
190     aReader.reset(OutputType::New());
191     //aReader = OutputType::New();
192     aReader->ReadFromInputStringOn();
193     aRet.reset(strOut.str());
194     aReader->SetInputString(aRet.get());
195     if(MYDEBUGWITHFILES){
196       string aMeshName = QString(theMeshName.c_str()).simplifyWhiteSpace().latin1();
197       string aGroupName = QString(theGroupName.c_str()).simplifyWhiteSpace().latin1();
198       string aFileName = string("/users/")+getenv("USER")+"/"+getenv("USER")+"-";
199       aFileName += aMeshName + "-" + aGroupName + "-Conv.vtk";
200       ofstream stmOut(aFileName.c_str(),ios::out);
201       stmOut<<aRet.get();
202     }
203   }
204   return aReader.get();
205   //return aReader;
206 }
207
208 VISU_Convertor::OutputType* VISU_Convertor_impl::GetFieldOnMesh(const string& theMeshName, 
209                                                                 const VISU::TEntity& theEntity,
210                                                                 const string& theFieldName,
211                                                                 int theStampsNum)
212      throw(std::runtime_error&)
213 {
214   if(!myIsDone) { myIsDone = true;  Build();}
215   if(MYDEBUG){
216     MESSAGE("GetFieldOnMesh - theMeshName = '"<<theMeshName<<"; theEntity = "<<theEntity);
217     MESSAGE("GetFieldOnMesh - theFieldName = '"<<theFieldName<<"'; theStampsNum = "<<theStampsNum);
218   }
219   //Cheching possibility do the query
220   if(myMeshMap.find(theMeshName) == myMeshMap.end())
221     throw std::runtime_error("GetFieldOnMesh >> There is no mesh with the name!!!");
222   VISU::TMesh& aMesh = myMeshMap[theMeshName];
223   VISU::TMeshOnEntityMap& aMeshOnEntityMap = aMesh.myMeshOnEntityMap;
224   if(aMeshOnEntityMap.find(theEntity) == aMeshOnEntityMap.end())
225     throw std::runtime_error("GetFieldOnMesh >> There is no mesh on the entity!!!");
226   VISU::TMeshOnEntity& aMeshOnEntity = aMeshOnEntityMap[theEntity];
227   VISU::TMeshOnEntity* pVtkMeshOnEntity = &aMeshOnEntity;
228   if(theEntity == VISU::NODE_ENTITY){
229     if(aMeshOnEntityMap.find(VISU::CELL_ENTITY) == aMeshOnEntityMap.end())
230       throw std::runtime_error("GetFieldOnMesh >> There is no mesh on CELL_ENTITY!!!");
231     pVtkMeshOnEntity = &aMeshOnEntityMap[VISU::CELL_ENTITY];
232   }
233   VISU::TMeshOnEntity& aVtkMeshOnEntity = *pVtkMeshOnEntity;
234   VISU::TFieldMap& aFieldMap = aMeshOnEntity.myFieldMap;
235   if(aFieldMap.find(theFieldName) == aFieldMap.end())
236     throw std::runtime_error("GetFieldOnMesh >> There is no field on the mesh!!!");
237   VISU::TField& aField = aFieldMap[theFieldName];
238   VISU::TField::TValField& aValField = aField.myValField;
239   if(aValField.find(theStampsNum) == aValField.end())
240     throw std::runtime_error("GetFieldOnMesh >> There is no field with the timestamp!!!");
241   VISU::TField::TValForTime& aValForTime = aValField[theStampsNum];
242   VISU::TVTKReader& aReader = aValForTime.myStorage;
243   //Main part of code
244   if(aReader.get() == NULL){
245     LoadFieldOnMesh(aMesh,aMeshOnEntity,aField,aValForTime);
246     try{
247       LoadMeshOnEntity(aVtkMeshOnEntity);
248     }catch(std::runtime_error& exc){
249       aVtkMeshOnEntity = aMeshOnEntity;
250       MESSAGE("Follow exception was accured :\n"<<exc.what());
251     }catch(...){
252       aVtkMeshOnEntity = aMeshOnEntity;
253       MESSAGE("Unknown exception was accured!");
254     }
255     ostrstream strOut;
256     strOut<<GetHead(theMeshName + dtos("-%d-",theEntity) + theFieldName + dtos("-%d",theStampsNum));
257     strOut<<GetPoints(aMesh);
258     pair<int,int> aCellsDim = aVtkMeshOnEntity.GetCellsDims();
259     int aNbCells = aCellsDim.first, aCellsSize = aCellsDim.second;
260     ostrstream strCellsOut, strTypesOut;
261     GetCells(strCellsOut,strTypesOut,aVtkMeshOnEntity);
262     strCellsOut<<ends;
263     strTypesOut<<ends;
264     strOut<<"CELLS "<<aNbCells<<"\t"<<aCellsSize<<endl;
265     auto_ptr<char> aRet(strCellsOut.str());
266     strOut<<aRet.get()<<endl;
267     strOut<<"CELL_TYPES "<<aNbCells<<endl;
268     aRet.reset(strTypesOut.str());
269     strOut<<aRet.get()<<endl;
270     int aNbPoints = aMesh.myPointsCoord.size()/aMesh.myDim;
271     strOut<<GetField(aField,aValForTime,aMesh.myDim,aNbPoints,aNbCells);
272     strOut<<ends;
273     aReader.reset(OutputType::New());
274     //aReader = OutputType::New();
275     aReader->ReadFromInputStringOn();
276     aRet.reset(strOut.str());
277     aReader->SetInputString(aRet.get());
278     if(MYDEBUGWITHFILES){
279       string aMeshName = QString(theMeshName.c_str()).simplifyWhiteSpace().latin1();
280       string aFieldName = QString(theFieldName.c_str()).simplifyWhiteSpace().latin1();
281       string aFileName = string("/users/")+getenv("USER")+"/"+getenv("USER")+"-";
282       aFileName += aMeshName + dtos("-%d-",theEntity) + aFieldName + dtos("-%d",theStampsNum) + "-Conv.vtk";
283       ofstream stmOut(aFileName.c_str(),ios::out);
284       stmOut<<aRet.get();
285     }
286   }
287   return aReader.get();
288   //return aReader;
289 }
290
291 inline void PrintCells(ostrstream& strCellsOut, const VISU::TMeshOnEntity::TConnect& theVector,
292                        ostrstream& strTypesOut, const int theVtkType)
293 {
294   strTypesOut<<theVtkType<<"\n";
295   int kEnd = theVector.size();
296   strCellsOut<<kEnd<<"\t";
297   for(int k = 0; k < kEnd; k++)
298     strCellsOut<<theVector[k]<<"\t";
299   strCellsOut<<endl;
300 }
301
302 int VISU_Convertor_impl::GetCells(ostrstream& strCellsOut, ostrstream& strTypesOut,
303                                   const VISU::TMeshOnEntity& theMeshOnEntity, 
304                                   const string& theFamilyName) const 
305        throw (std::runtime_error&)
306 {
307   //Check on existing family
308   const VISU::TFamily* pFamily = VISU::GetFamily(theMeshOnEntity,theFamilyName);
309   bool isFamilyPresent = (pFamily != NULL);
310   const VISU::TFamily& aFamily = *pFamily;
311   //Main part of code
312   if(MYDEBUG) MESSAGE("GetCells - isFamilyPresent = "<<isFamilyPresent);
313   const VISU::TMeshOnEntity::TCellsConn &aCellsConn = theMeshOnEntity.myCellsConn;
314   VISU::TMeshOnEntity::TCellsConn::const_iterator aCellsConnIter = aCellsConn.begin();
315   for(; aCellsConnIter != aCellsConn.end(); aCellsConnIter++){
316     const VISU::TMeshOnEntity::TConnForCellType& anArray = aCellsConnIter->second;
317     int aVtkType = aCellsConnIter->first;
318     if(MYDEBUG) MESSAGE("GetCells - aVtkType = "<<aVtkType<<"; anArray.size() = "<<anArray.size());
319     if(!isFamilyPresent)
320       for(int j = 0, jEnd = anArray.size(); j < jEnd; j++)
321         PrintCells(strCellsOut,anArray[j],strTypesOut,aVtkType);
322     else{
323       const VISU::TFamily::TSubMesh& aSubMesh = aFamily.mySubMesh;
324       if(aSubMesh.empty()) throw std::runtime_error("GetCells >> There is no elements on the family !!!");
325       VISU::TFamily::TSubMesh::const_iterator aSubMeshIter = aSubMesh.find(aVtkType);
326       if(aSubMeshIter == aSubMesh.end()) continue;
327       const VISU::TFamily::TSubMeshOnCellType& aSubMeshOnCellType = aSubMeshIter->second;
328       if(MYDEBUG) MESSAGE("GetCells - aSubMeshOnCellType.size() = "<<aSubMeshOnCellType.size());
329       VISU::TFamily::TSubMeshOnCellType::const_iterator aSubMeshOnCellTypeIter = aSubMeshOnCellType.begin();
330       for(; aSubMeshOnCellTypeIter != aSubMeshOnCellType.end(); aSubMeshOnCellTypeIter++)
331         PrintCells(strCellsOut,anArray[*aSubMeshOnCellTypeIter],strTypesOut,aVtkType);
332     }
333   }
334   return 1; 
335 }
336
337 string VISU_Convertor_impl::GetHead(const string& theMeshName) const throw (std::runtime_error&){
338   ostrstream strOut;
339   strOut<<"# vtk DataFile Version 3.2\n";
340   strOut<<theMeshName<<endl;
341   strOut<<"ASCII\n";
342   strOut<<"DATASET UNSTRUCTURED_GRID\n";
343   strOut<<ends;
344   auto_ptr<char> aRet(strOut.str());
345   return aRet.get(); 
346 }
347
348 string VISU_Convertor_impl::GetPoints(const VISU::TMesh& theMesh) const 
349        throw (std::runtime_error&)
350 {
351   ostrstream strOut;
352   strOut.setf(ios::scientific,ios::floatfield);  strOut.precision(PRECISION);
353   const VISU::TMesh::TPointsCoord& anArray = theMesh.myPointsCoord;
354   int iEnd = theMesh.myPointsCoord.size();
355   int aNbPoints = iEnd/theMesh.myDim;
356   strOut<<"POINTS "<<aNbPoints<<" float\n";
357   if(MYDEBUG) 
358     MESSAGE("GetPoints - aNbPoints = "<<aNbPoints<<"; myDim = "<<theMesh.myDim);
359   switch(theMesh.myDim) {
360   case 1:
361     for (int i = 0; i < iEnd;) 
362       strOut<<anArray[i++]<<"\n";
363     break;
364   case 2:
365     for (int i = 0; i < iEnd;){
366       strOut<<anArray[i++]<<"\t";
367       strOut<<anArray[i++]<<"\t";
368       strOut<<0.0<<"\n";
369     }
370     break;
371   case 3: 
372     for (int i = 0; i < iEnd;){
373       strOut<<anArray[i++]<<"\t";
374       strOut<<anArray[i++]<<"\t";
375       strOut<<anArray[i++]<<"\n";
376     }
377     break;
378   }
379   strOut<<ends;
380   auto_ptr<char> aRet(strOut.str());
381   return aRet.get(); 
382 }
383
384 string VISU_Convertor_impl::GetField(const VISU::TField& theField, 
385                                      const VISU::TField::TValForTime& theValForTime,
386                                      int theDim, int theNbPoints, int theNbCells) const 
387        throw (std::runtime_error&)
388 {
389   ostrstream strOut;
390   strOut.setf(ios::scientific,ios::floatfield);  strOut.precision(PRECISION);
391   string aName = GenerateName(theField.myName,theValForTime.myId);
392   if(MYDEBUG) MESSAGE("GetField - aTime = "<<theValForTime.myId<<"; aName = "<<aName);
393   switch(theField.myEntity) {
394   case VISU::NODE_ENTITY :
395     strOut<<"POINT_DATA "<<theNbPoints<<"\n";
396     break;
397   default:
398     strOut<<"CELL_DATA "<<theNbCells<<"\n";
399   }
400   switch(theField.myNbComp) {
401   case 1:
402     strOut<<"SCALARS "<<aName<<" float\n";
403     strOut<<"LOOKUP_TABLE default\n";
404     break;
405   default:
406     strOut<<"VECTORS "<<aName<<" float\n";
407     break;
408   }
409   const VISU::TField::TValForCells& aValForCells = theValForTime.myValForCells;
410   VISU::TField::TValForCells::const_iterator aValForCellsIter = aValForCells.begin();
411   for(; aValForCellsIter != aValForCells.end(); aValForCellsIter++) {
412     const VISU::TField::TValForCellsWithType& anArray = aValForCellsIter->second;
413     int iEnd = anArray.size()/theField.myNbComp;
414     int aVtkType = aValForCellsIter->first;
415     if(MYDEBUG) MESSAGE("GetField -  iEnd = "<<iEnd<<"; aVtkType = "<<aVtkType<<"; theDim = "<<theDim);
416     if(theField.myNbComp == 1){
417       for (int i = 0; i < iEnd;) strOut<<anArray[i++]<<"\n";
418     }else if(theDim == 2){
419       for (int i = 0, ji = 0; i < iEnd; ji = (++i)*theField.myNbComp){
420         strOut<<anArray[ji++]<<"\t";
421         strOut<<anArray[ji++]<<"\t";
422         strOut<<0.0<<"\n";
423       }
424     }else if(theDim == 3){
425       for (int i = 0, ji = 0; i < iEnd; ji = (++i)*theField.myNbComp){
426         strOut<<anArray[ji++]<<"\t";
427         strOut<<anArray[ji++]<<"\t";
428         strOut<<anArray[ji++]<<"\n";
429       }
430     }else
431       throw std::runtime_error("GetField - There is algorithm for representation the field !!!");
432   }
433   strOut<<ends;
434   auto_ptr<char> aRet(strOut.str());
435   return aRet.get(); 
436 }