1 // Copyright (C) 2003 CEA/DEN, EDF R&D
5 // File : VISU_Convertor_impl.cxx
6 // Author : Alexey PETROV
10 #include "VISU_Convertor_impl.hxx"
12 #include <vtkUnstructuredGridReader.h>
14 #include <qfileinfo.h>
15 #include <vtkCellType.h>
21 static int MYDEBUG = 0;
22 static int MYDEBUGWITHFILES = 0;
24 static int MYDEBUG = 0;
25 static int MYDEBUGWITHFILES = 0;
27 static int PRECISION = 7;
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)
51 VISU_Convertor* CreateConvertor(const string& theFileName) throw(std::runtime_error&){
52 if(QFileInfo(theFileName.c_str()).extension(false) == "med")
53 return CreateMedConvertor(theFileName);
55 return CreateDatConvertor(theFileName);
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;
64 int getNbMedNodes(int geom){
68 int getIdMedType(int medType){
69 for(int i = 0; i < MED_NBR_GEOMETRIE_MAILLE; i++)
70 if(med2vtk[i].medType == medType) return i;
75 VISU_Convertor_impl::VISU_Convertor_impl() {
79 VISU_Convertor_impl::~VISU_Convertor_impl() {}
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&)
86 if(!myIsDone) { myIsDone = true; Build();}
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;
101 pReader = &(pFamily->myStorage);
103 pReader = &(aMeshOnEntity.myStorage);
104 VISU::TVTKReader& aReader = *pReader;
106 if(aReader.get() == NULL){
107 LoadMeshOnEntity(aMeshOnEntity,theFamilyName);
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);
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;
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());
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);
141 return aReader.get();
145 VISU_Convertor::OutputType* VISU_Convertor_impl::GetMeshOnGroup(const string& theMeshName,
146 const string& theGroupName)
147 throw(std::runtime_error&)
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);
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);
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;
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);
204 return aReader.get();
208 VISU_Convertor::OutputType* VISU_Convertor_impl::GetFieldOnMesh(const string& theMeshName,
209 const VISU::TEntity& theEntity,
210 const string& theFieldName,
212 throw(std::runtime_error&)
214 if(!myIsDone) { myIsDone = true; Build();}
216 MESSAGE("GetFieldOnMesh - theMeshName = '"<<theMeshName<<"; theEntity = "<<theEntity);
217 MESSAGE("GetFieldOnMesh - theFieldName = '"<<theFieldName<<"'; theStampsNum = "<<theStampsNum);
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];
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;
244 if(aReader.get() == NULL){
245 LoadFieldOnMesh(aMesh,aMeshOnEntity,aField,aValForTime);
247 LoadMeshOnEntity(aVtkMeshOnEntity);
248 }catch(std::runtime_error& exc){
249 aVtkMeshOnEntity = aMeshOnEntity;
250 MESSAGE("Follow exception was accured :\n"<<exc.what());
252 aVtkMeshOnEntity = aMeshOnEntity;
253 MESSAGE("Unknown exception was accured!");
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);
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);
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);
287 return aReader.get();
291 inline void PrintCells(ostrstream& strCellsOut, const VISU::TMeshOnEntity::TConnect& theVector,
292 ostrstream& strTypesOut, const int theVtkType)
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";
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&)
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;
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());
320 for(int j = 0, jEnd = anArray.size(); j < jEnd; j++)
321 PrintCells(strCellsOut,anArray[j],strTypesOut,aVtkType);
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);
337 string VISU_Convertor_impl::GetHead(const string& theMeshName) const throw (std::runtime_error&){
339 strOut<<"# vtk DataFile Version 3.2\n";
340 strOut<<theMeshName<<endl;
342 strOut<<"DATASET UNSTRUCTURED_GRID\n";
344 auto_ptr<char> aRet(strOut.str());
348 string VISU_Convertor_impl::GetPoints(const VISU::TMesh& theMesh) const
349 throw (std::runtime_error&)
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";
358 MESSAGE("GetPoints - aNbPoints = "<<aNbPoints<<"; myDim = "<<theMesh.myDim);
359 switch(theMesh.myDim) {
361 for (int i = 0; i < iEnd;)
362 strOut<<anArray[i++]<<"\n";
365 for (int i = 0; i < iEnd;){
366 strOut<<anArray[i++]<<"\t";
367 strOut<<anArray[i++]<<"\t";
372 for (int i = 0; i < iEnd;){
373 strOut<<anArray[i++]<<"\t";
374 strOut<<anArray[i++]<<"\t";
375 strOut<<anArray[i++]<<"\n";
380 auto_ptr<char> aRet(strOut.str());
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&)
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";
398 strOut<<"CELL_DATA "<<theNbCells<<"\n";
400 switch(theField.myNbComp) {
402 strOut<<"SCALARS "<<aName<<" float\n";
403 strOut<<"LOOKUP_TABLE default\n";
406 strOut<<"VECTORS "<<aName<<" float\n";
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";
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";
431 throw std::runtime_error("GetField - There is algorithm for representation the field !!!");
434 auto_ptr<char> aRet(strOut.str());