Salome HOME
NRI : Set correct name of MED component for import MED object.
[modules/visu.git] / src / VISU_I / VISU_Result_i.cc
1 //  Copyright (C) 2003  CEA/DEN, EDF R&D
2 //
3 //
4 //
5 //  File   : VISU_Result_i.cc
6 //  Author : Alexey PETROV
7 //  Module : VISU
8
9 using namespace std;
10 #include "VISU_Result_i.hh"
11 #include "VISU_Convertor_impl.hxx"
12 #include "VISU_CorbaMedConvertor.hxx"
13 #include "VISU_Extractor.hxx"
14 using namespace VISU;
15
16 #include "SALOMEDS_Tool.hxx"
17 #include "HDFascii.hxx"
18
19 #include <qstring.h>
20 #include <qfileinfo.h>
21
22 #include <fstream>      
23
24 #include <vtkUnstructuredGridReader.h>
25 #include <vtkUnstructuredGridWriter.h>
26
27 using namespace std;
28
29 #ifdef DEBUG
30 static int MYDEBUG = 0;
31 static int MYDEBUGWITHFILES = 0;
32 #else
33 static int MYDEBUG = 0;
34 static int MYDEBUGWITHFILES = 0;
35 #endif
36
37 VISU::Result_var VISU::FindResult(SALOMEDS::SObject_ptr theSObject){
38   SALOMEDS::SComponent_var aSComponent = theSObject->GetFatherComponent();
39   SALOMEDS::SObject_var aFather = theSObject->GetFather();
40   CORBA::String_var aComponentID(aSComponent->GetID());
41   CORBA::String_var aFatherID(aFather->GetID());
42   VISU::Result_var aResult;
43   while(strcmp(aComponentID,aFatherID) != 0){
44     CORBA::Object_var anObject = VISU::SObjectToObject(aFather);
45     if(!CORBA::is_nil(anObject)){
46       aResult = VISU::Result::_narrow(anObject);
47       if(!aResult->_is_nil()) return aResult;
48     }
49     aFather = aFather->GetFather();
50   }
51   return aResult;
52 }
53
54 QString VISU::GenerateName(const string& theFmt, int theId){
55   static QString aName;
56   if(theId > 0)
57     aName.sprintf("%s:%d",theFmt.c_str(),theId);
58   else
59     aName.sprintf("%s",theFmt.c_str());
60   return aName;
61 }
62
63 void VISU::WriteToFile(vtkUnstructuredGrid* theDataSet, const string& theFileName){
64   vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
65   aWriter->SetFileName(theFileName.c_str());
66   aWriter->SetInput(theDataSet);
67   aWriter->Write();
68   aWriter->Delete();
69 }
70
71 QString GenerateName(const char* theName){
72   typedef map<string,int> TNameMap;
73   static TNameMap aMap;
74   TNameMap::const_iterator i = aMap.find(theName);
75   QString tmp;
76   if(i == aMap.end()) {
77     aMap[theName] = 0;
78     tmp = theName;
79   }else{
80     tmp = VISU::GenerateName(theName,++aMap[theName]);
81   }
82   if(MYDEBUG) MESSAGE("GenerateName - "<<tmp<<" from - "<<theName<<"; " <<aMap[theName]);
83   return tmp;
84 }
85
86 QString GenerateFieldName(const string& theName, const string& theUnits){
87   static QString aName;
88   const string tmp(theUnits.size(),' ');
89   if(theUnits == "" || theUnits == tmp)
90     aName.sprintf("%s, -",theName.c_str());
91   else
92     aName.sprintf("%s, %s",theName.c_str(),theUnits.c_str());
93   aName = aName.simplifyWhiteSpace();
94   return aName.latin1();
95 }
96
97 void CreateReference(SALOMEDS::Study_ptr theStudyDocument, 
98                      const string& theFatherEntry, const string& theRefEntry)
99 {
100   SALOMEDS::StudyBuilder_var aStudyBuilder = theStudyDocument->NewBuilder();
101   SALOMEDS::SObject_var aFather = theStudyDocument->FindObjectID(theFatherEntry.c_str());
102   SALOMEDS::SObject_var newObj = aStudyBuilder->NewObject(aFather);
103   SALOMEDS::SObject_var aRefSObj = theStudyDocument->FindObjectID(theRefEntry.c_str());
104   aStudyBuilder->Addreference(newObj,aRefSObj);
105 }
106
107 string GetComponentDataType(SALOMEDS::SObject_ptr theSObject){
108   SALOMEDS::SComponent_var aCompRefSObj = theSObject->GetFatherComponent();
109   CORBA::String_var aDataType = aCompRefSObj->ComponentDataType();
110   return aDataType.in();
111 }
112
113 //==============================================================================
114
115 const string VISU::Result_i::myComment = "RESULT";
116 const char* VISU::Result_i::GetComment() const { return myComment.c_str();}
117
118 VISU::Result_i::Result_i(SALOMEDS::Study_ptr theStudy) {
119   myStudyDocument = SALOMEDS::Study::_duplicate(theStudy);
120   myInput = NULL;
121 }
122
123 VISU::Storable* VISU::Result_i::Build(SALOMEDS::SObject_ptr theSObject) 
124      throw (std::runtime_error&)
125 {
126   if(MYDEBUG) MESSAGE("Result_i::Build");
127   const TMeshMap& aMeshMap = myInput->GetMeshMap();
128   if(!aMeshMap.empty()) {//apo
129     mySComponent = FindOrCreateVisuComponent(myStudyDocument);
130     CORBA::String_var aSComponentEntry = mySComponent->GetID(), anIOR(GetID());
131     string aRefFatherEntry = GetRefFatherEntry();
132     QString aComment;
133     aComment.sprintf("myComment=%s;myType=%d;myFileName=%s",
134                      GetComment(),VISU::TRESULT,myFileInfo.filePath().latin1());
135     string aResultEntry = CreateAttributes(myStudyDocument,aSComponentEntry,aRefFatherEntry.c_str(),
136                                            anIOR,myName.c_str(),"",aComment.latin1(),true);
137     mySObject = myStudyDocument->FindObjectID(aResultEntry.c_str());
138     if(mySObject->_is_nil()) throw std::runtime_error("Build - There is no SObject for the Result !!!");
139     if(theSObject != NULL){
140       CORBA::String_var aString = theSObject->GetID();
141       CreateReference(myStudyDocument,aResultEntry,aString.in());
142     }
143     TMeshMap::const_iterator aMeshMapIter = aMeshMap.begin();
144     for(; aMeshMapIter != aMeshMap.end(); aMeshMapIter++){
145       const string& aMeshName = aMeshMapIter->first;
146       const VISU::TMesh& aMesh = aMeshMapIter->second;
147       const VISU::TMeshOnEntityMap& aMeshOnEntityMap = aMesh.myMeshOnEntityMap;
148       VISU::TMeshOnEntityMap::const_iterator aMeshOnEntityMapIter;
149       aComment.sprintf("myComment=MESH;myName=%s;myDim=%d",
150                        aMeshName.c_str(),aMesh.myDim);
151       string aMeshEntry = CreateAttributes(myStudyDocument,aResultEntry.c_str(),aRefFatherEntry.c_str(),
152                                            "",aMeshName.c_str(),"",aComment.latin1(),true);
153       if(aMeshOnEntityMap.empty()) continue;
154       aComment.sprintf("myComment=FAMILIES;myMeshName=%s",aMeshName.c_str());
155       string aSubMeshesEntry = CreateAttributes(myStudyDocument,aMeshEntry.c_str(),aRefFatherEntry.c_str(),
156                                                 "","Families","",aComment.latin1(),true);
157       //Import entities and according families
158       aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
159       typedef map<VISU::TEntity,string> TEntity2Entry;
160       TEntity2Entry aEntity2Entry;
161       for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++){
162         const VISU::TEntity& anEntity = aMeshOnEntityMapIter->first;
163         aComment.sprintf("myComment=ENTITY;myType=%d;myMeshName=%s;myId=%d",
164                          VISU::TENTITY,aMeshName.c_str(),anEntity);
165         string anEntityName;
166         switch(anEntity){
167         case VISU::NODE_ENTITY : anEntityName = "onNodes"; break;
168         case VISU::EDGE_ENTITY : anEntityName = "onEdges"; break;
169         case VISU::FACE_ENTITY : anEntityName = "onFaces"; break;
170         case VISU::CELL_ENTITY : anEntityName = "onCells"; break;
171         default:
172           throw std::runtime_error("Build >> Value of entity is incorrect!");
173         }
174         aEntity2Entry[anEntity] = CreateAttributes(myStudyDocument,aSubMeshesEntry.c_str(),aRefFatherEntry.c_str(),
175                                                    "",anEntityName.c_str(),"",aComment.latin1(),true);
176         const VISU::TMeshOnEntity& aMeshOnEntity = aMeshOnEntityMapIter->second;
177         const VISU::TFamilyMap& aFamilyMap = aMeshOnEntity.myFamilyMap;
178         VISU::TFamilyMap::const_iterator aFamilyMapIter = aFamilyMap.begin();
179         for(; aFamilyMapIter != aFamilyMap.end(); aFamilyMapIter++){
180           const string& aFamilyName = aFamilyMapIter->first;
181           aComment.sprintf("myComment=FAMILY;myType=%d;myMeshName=%s;myEntityId=%d;myName=%s",
182                            VISU::TFAMILY,aMeshName.c_str(),anEntity,aFamilyName.c_str());
183           CreateAttributes(myStudyDocument,aEntity2Entry[anEntity].c_str(),aRefFatherEntry.c_str(),
184                            "",aFamilyName.c_str(),"",aComment.latin1(),true);
185         }
186       }
187       //Importing groups
188       const VISU::TGroupMap& aGroupMap = aMesh.myGroupMap;
189       if(aGroupMap.size() > 0){
190         aComment.sprintf("myComment=GROUPS;myMeshName=%s",aMeshName.c_str());
191         string aGroupsEntry = CreateAttributes(myStudyDocument,aMeshEntry.c_str(),aRefFatherEntry.c_str(),
192                                                "","Groups","",aComment.latin1(),true);
193         VISU::TGroupMap::const_iterator aGroupMapIter = aGroupMap.begin();
194         for(; aGroupMapIter != aGroupMap.end(); aGroupMapIter++){
195           const string& aGroupName = aGroupMapIter->first;
196           aComment.sprintf("myComment=GROUP;myType=%d;myMeshName=%s;myName=%s",
197                            VISU::TGROUP,aMeshName.c_str(),aGroupName.c_str());
198           string aGroupEntry = CreateAttributes(myStudyDocument,aGroupsEntry.c_str(),aRefFatherEntry.c_str(),
199                                                 "",aGroupName.c_str(),"",aComment.latin1(),true);
200           const VISU::TGroup& aGroup = aGroupMapIter->second;
201           const VISU::TFamilyAndEntitySet& aFamilyAndEntitySet = aGroup.myFamilyAndEntitySet;
202           VISU::TFamilyAndEntitySet::const_iterator aFamilyAndEntitySetIter = aFamilyAndEntitySet.begin();
203           for(; aFamilyAndEntitySetIter != aFamilyAndEntitySet.end(); aFamilyAndEntitySetIter++){
204             const VISU::TFamilyAndEntity& aFamilyAndEntity = *aFamilyAndEntitySetIter;
205             const string& aFamilyName = aFamilyAndEntity.first;
206             const VISU::TEntity& anEntity = aFamilyAndEntity.second;
207             aComment.sprintf("myComment=FAMILY;myType=%d;myMeshName=%s;myEntityId=%d;myName=%s",
208                              VISU::TFAMILY,aMeshName.c_str(),anEntity,aFamilyName.c_str());
209             string anEntry = FindEntryWithComment(myStudyDocument,aEntity2Entry[anEntity].c_str(),aComment);
210             CreateReference(myStudyDocument,aGroupEntry,anEntry);
211           }
212         }
213       }
214       //Import fields
215       string aFieldsEntry;
216       bool isFieldEntryCreated = 0;
217       aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
218       for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++){
219         const VISU::TEntity& anEntity = aMeshOnEntityMapIter->first;
220         const VISU::TMeshOnEntity& aMeshOnEntity = aMeshOnEntityMapIter->second;
221         const VISU::TFieldMap& aFieldMap = aMeshOnEntity.myFieldMap;
222         VISU::TFieldMap::const_iterator aFieldMapIter = aFieldMap.begin();
223         for(; aFieldMapIter != aFieldMap.end(); aFieldMapIter++){
224           if(!isFieldEntryCreated){
225             aComment.sprintf("myComment=FIELDS;myMeshName=%s",aMeshName.c_str());
226             aFieldsEntry = CreateAttributes(myStudyDocument,aMeshEntry.c_str(),aRefFatherEntry.c_str(),
227                                             "","Fields","",aComment.latin1(),true);
228             isFieldEntryCreated = true;
229           }
230           const string& aFieldName = aFieldMapIter->first;
231           const VISU::TField& aField = aFieldMapIter->second;
232           const VISU::TField::TValField& aValField = aField.myValField;
233           QString aFieldNameWithUnit = ::GenerateFieldName(aFieldName,aField.myUnitNames[0]);
234           aComment.sprintf("myComment=FIELD;myType=%d;myMeshName=%s;myEntityId=%d;myName=%s;myNbTimeStamps=%d;myNumComponent=%d",
235                            VISU::TFIELD,aMeshName.c_str(),anEntity,aFieldName.c_str(),aValField.size(),aField.myNbComp);
236           string aFieldEntry = CreateAttributes(myStudyDocument,aFieldsEntry.c_str(),aRefFatherEntry.c_str(),
237                                                 "",aFieldNameWithUnit.latin1(),"",aComment.latin1(),true);
238           CreateReference(myStudyDocument,aFieldEntry,aEntity2Entry[anEntity]);
239           VISU::TField::TValField::const_iterator aValFieldIter = aValField.begin();
240           for(; aValFieldIter != aValField.end(); aValFieldIter++){
241             int aTimeStamp = aValFieldIter->first;
242             const VISU::TField::TValForTime& aValForTime = aValFieldIter->second;
243             aComment.sprintf("myComment=TIMESTAMP;myType=%d;myMeshName=%s;myEntityId=%d;myFieldName=%s;myTimeStampId=%d;myNumComponent=%d",
244                              VISU::TTIMESTAMP,aMeshName.c_str(),anEntity,aFieldName.c_str(),aTimeStamp,aField.myNbComp);
245             string aTimeStampId = VISU_Convertor::GenerateName(aValForTime.myTime);
246             CreateAttributes(myStudyDocument,aFieldEntry.c_str(),aRefFatherEntry.c_str(),
247                              "",aTimeStampId.c_str(),"",aComment.latin1(),true);
248           }
249         }
250       }
251     }
252   }
253   return this;
254 }
255
256 VISU::Storable* VISU::Result_i::Create(const char* theFileName){
257   try{
258     mySourceId = eFile;
259     myInput = CreateConvertor(theFileName);
260     if(myInput == NULL) return NULL;
261     myFileInfo.setFile(theFileName);
262     myName = (const char*)(::GenerateName(myFileInfo.fileName().latin1()));
263     VISU::Storable* aStorable = Build();
264     return aStorable;
265   }catch(std::runtime_error& exc){
266     MESSAGE("Follow exception was accured :\n"<<exc.what());
267   }catch(...){
268     MESSAGE("Unknown exception was accured!");
269   }
270   return NULL;
271 }
272
273 VISU::Storable* VISU::Result_i::Create(SALOMEDS::SObject_ptr theMedSObject){
274   if(MYDEBUG)  MESSAGE("Result_i::Create MedObject from SALOMEDS::SObject_ptr");
275   try{
276     mySourceId = eComponent;
277     myInput = CreateMEDConvertor(theMedSObject);
278     if(myInput == NULL) return NULL;
279     string aCompDataType = GetComponentDataType(theMedSObject);
280     myFileInfo.setFile(aCompDataType.c_str());
281     myName = (const char*)(::GenerateName("aResult"));
282     VISU::Storable* aStorable = Build(theMedSObject);
283     return aStorable;
284   }catch(std::runtime_error& exc){
285     MESSAGE("Follow exception was accured :\n"<<exc.what());
286   }catch(...){
287     MESSAGE("Unknown exception was accured!");
288   }
289   return NULL;
290 }
291
292 VISU::Storable* VISU::Result_i::Create(SALOME_MED::FIELD_ptr theField){
293   if(MYDEBUG)  MESSAGE("Result_i::Create MedObject from SALOME_MED::FIELD_ptr");
294   try{
295     mySourceId = eComponent;
296     myInput = CreateMEDFieldConvertor(theField);
297     if(myInput == NULL) return NULL;
298     string aCompDataType = "MED";
299     myFileInfo.setFile(aCompDataType.c_str());
300     myName = (const char*)(::GenerateName("aResult"));
301     VISU::Storable* aStorable = Build();
302     return aStorable;
303   }catch(std::runtime_error& exc){
304     MESSAGE("Follow exception was accured :\n"<<exc.what());
305   }catch(...){
306     MESSAGE("Unknown exception was accured!");
307   }
308   return NULL;
309 }
310
311 VISU::Storable* VISU::Result_i::Restore(SALOMEDS::SObject_ptr theSObject, 
312                                         const string& thePrefix, const Storable::TRestoringMap& theMap)
313      throw(std::logic_error&)
314 {
315   if(MYDEBUG)  MESSAGE("Result_i::Restore - "<<thePrefix);
316   try{
317     mySObject = SALOMEDS::SObject::_duplicate(theSObject);
318     myStudyDocument = mySObject->GetStudy();
319     mySComponent = mySObject->GetFatherComponent();
320     myName = (const char*)(VISU::Storable::FindValue(theMap,"myName"));
321     SALOMEDS::SObject_var aRefSObj, aTargetRefSObj;
322     if(mySObject->FindSubObject(1,aRefSObj) && aRefSObj->ReferencedObject(aTargetRefSObj)){
323       mySourceId = eRestoredComponent;
324       if(MYDEBUG)  MESSAGE("Result_i::GetInput - There is some reference.");
325       SALOMEDS::SComponent_var aCompRefSObj = aTargetRefSObj->GetFatherComponent();
326       CORBA::String_var aDataType = aCompRefSObj->ComponentDataType();
327       myFileInfo.setFile(aDataType.in());
328       if(MYDEBUG)  MESSAGE("Result_i::GetInput - aDataType = "<<aDataType);
329       Engines::Component_var aEngComp = Base_i::myEnginesLifeCycle->FindOrLoad_Component("FactoryServer", aDataType.in());
330       if (CORBA::is_nil(aEngComp)) 
331         throw std::runtime_error("Restore - There is no aEngComp for the aDataType !!!");
332       SALOMEDS::StudyBuilder_var  aStudyBuilder = myStudyDocument->NewBuilder();
333       SALOMEDS::Driver_var aDriver = SALOMEDS::Driver::_narrow(aEngComp);
334       aStudyBuilder->LoadWith(aCompRefSObj,aDriver);
335       if(strcmp(aDataType,"MED") == 0){
336         myInput = CreateMEDConvertor(aTargetRefSObj);
337       }else
338         throw std::runtime_error("GetInput - There is no convertor for the aDataType !!!");
339     }else{
340       myFileInfo.setFile(thePrefix.c_str());
341
342       string aStudyPrefix(SALOMEDS_Tool::GetNameFromPath(myStudyDocument->URL()));
343       if(!myFileInfo.isFile()){
344         string aFileName = thePrefix + aStudyPrefix + "_" + myName;
345         myFileInfo.setFile(aFileName.c_str());
346       }
347       if(MYDEBUG)  
348         MESSAGE("Result_i::Restore - aFileName = "<<myFileInfo.filePath()<<"; "<<myFileInfo.isFile());
349
350       if (HDFascii::isASCII(myFileInfo.filePath().latin1())) {
351         char* aResultPath = HDFascii::ConvertFromASCIIToHDF(myFileInfo.filePath().latin1());
352         char* aHDFFileName = new char[strlen(aResultPath) + 19];
353         sprintf(aHDFFileName, "%shdf_from_ascii.hdf", aResultPath);
354
355         if (IsMultifile()) { // set this file as new - temporary
356           static QString aCommand;
357           aCommand.sprintf("mv %s %s%s",aHDFFileName, aResultPath, myFileInfo.baseName().latin1());
358           if(system(aCommand) == -1){
359             if(MYDEBUG) MESSAGE("VISU::Result_i::Restore - Can't execute the command :"<<aCommand);
360             return NULL;
361           } else if(MYDEBUG) MESSAGE("VISU::Result_i::Restore - "<<aCommand);
362           myFileInfo.setFile(QString(aResultPath)+QString(myFileInfo.baseName().latin1()));
363         } else { // change current temporary file to the new: with hdf-format
364           static QString aCommand;
365           aCommand.sprintf("mv %s %s\0",aHDFFileName, myFileInfo.filePath().latin1());
366           if(system(aCommand.latin1()) == -1) {
367             if(MYDEBUG) MESSAGE("VISU::Result_i::Restore - Can't execute the command :"<<aCommand);
368             return NULL;
369           } else if(MYDEBUG) MESSAGE("VISU::Result_i::Restore - "<<aCommand);
370           SALOMEDS::ListOfFileNames_var anEmptyList = new SALOMEDS::ListOfFileNames;
371           SALOMEDS_Tool::RemoveTemporaryFiles(aResultPath, anEmptyList, true);
372         }
373         mySourceId = eRestoredFile;
374         delete(aResultPath);
375         delete(aHDFFileName);
376       } else if (!IsMultifile()) mySourceId = eRestoredFile;
377       else mySourceId = eFile;
378
379       myInput = CreateMedConvertor(myFileInfo.filePath().latin1());
380       QString aComment;
381       aComment.sprintf("myComment=%s;myType=%d;myName=%s;myFileName=%s",
382                        GetComment(),VISU::TRESULT,myName.c_str(),myFileInfo.filePath().latin1());
383       SALOMEDS::GenericAttribute_var anAttr;
384       if(!theSObject->FindAttribute(anAttr, "AttributeComment"))
385         throw std::runtime_error("Build - There is no AttributeComment for the SObject !!!");
386       SALOMEDS::AttributeComment_var aCmnt = SALOMEDS::AttributeComment::_narrow(anAttr);
387       aCmnt->SetValue(aComment.latin1());
388     }
389     return this;
390   }catch(std::runtime_error& exc){
391     MESSAGE("Follow exception was accured :\n"<<exc.what());
392   }catch(...){
393     MESSAGE("Unknown exception was accured!");
394   }
395   return NULL;
396 }
397
398 VISU::Result_i::InputType* VISU::Result_i::GetInput() { 
399   return myInput;
400 }
401
402 void VISU::Result_i::ToStream(std::ostringstream& theStr){
403   if(MYDEBUG) MESSAGE(GetComment());
404   Storable::DataToStream(theStr,"myName",myName.c_str());
405 }
406
407 VISU::Storable* VISU::ResultRestore(SALOMEDS::SObject_ptr theSObject, 
408                                     const string& thePrefix, const Storable::TRestoringMap& theMap)
409      throw(std::logic_error&)
410 {
411   SALOMEDS::Study_var aStudy = theSObject->GetStudy();
412   VISU::Result_i* pResult = new VISU::Result_i(aStudy);
413   if(pResult == NULL) return NULL;
414   return pResult->Restore(theSObject,thePrefix,theMap);
415 }
416      
417 string VISU::Result_i::GetRefFatherEntry() { 
418   //return QAD_Application::getDesktop()->getActiveStudy()->getActiveStudyFrame()->entry();
419   return "";
420 }
421
422 string VISU::Result_i::GetEntry(){ 
423   CORBA::String_var anEntry = mySObject->GetID();
424   return string(anEntry);
425 }
426
427 const SALOMEDS::SObject_var& VISU::Result_i::GetSObject() const { return mySObject;}
428 const SALOMEDS::Study_var& VISU::Result_i::GetStudyDocument() const { return myStudyDocument;}
429 const SALOMEDS::SComponent_var& VISU::Result_i::GetSComponent() const { return mySComponent;}
430
431 VISU::Result_i::~Result_i() {
432   if(MYDEBUG) MESSAGE("Result_i::~Result_i()");
433   if(myInput) delete myInput;
434 }