Salome HOME
Merge with branch V2_2_0_VISU_improvement
[modules/visu.git] / src / VISU_I / VISU_Result_i.cc
1 //  VISU OBJECT : interactive object for VISU entities implementation
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
21 //
22 //
23 //  File   : VISU_Result_i.cc
24 //  Author : Alexey PETROV
25 //  Module : VISU
26
27 #include "VISU_Result_i.hh"
28
29 #include "VISU_Prs3d_i.hh"
30 #include "VISU_ViewManager_i.hh"
31
32 #include "VISU_Convertor_impl.hxx"
33 #include "VISU_CorbaMedConvertor.hxx"
34 #include "VISU_PipeLine.hxx"
35 #include "VISU_Actor.h"
36
37 //#include "SVTK_ViewWindow.h"
38
39 //#include "QAD_Desktop.h"
40 //#include "QAD_Application.h"
41 //#include "QAD_Study.h"
42 //#include "QAD_StudyFrame.h"
43 //#include "QAD_RightFrame.h"
44
45 #include "SUIT_ResourceMgr.h"
46 #include "SALOMEDS_Tool.hxx"
47 #include "HDFascii.hxx"
48
49 #include <qstring.h>
50 #include <qfileinfo.h>
51
52 #include <memory>
53 #include <fstream>
54 //#include <set>
55
56 #include <vtkUnstructuredGridReader.h>
57 #include <vtkUnstructuredGridWriter.h>
58 #include <vtkCell.h>
59
60 #include <gp_Pnt.hxx>
61 #include <gp_Vec.hxx>
62 #include <Bnd_Box.hxx>
63
64 using namespace VISU;
65 using namespace std;
66
67 #ifdef _DEBUG_
68 static int MYDEBUG = 0;
69 #else
70 static int MYDEBUG = 0;
71 #endif
72
73 VISU::Result_var VISU::FindResult(SALOMEDS::SObject_ptr theSObject){
74   SALOMEDS::SComponent_var aSComponent = theSObject->GetFatherComponent();
75   SALOMEDS::SObject_var aFather = theSObject->GetFather();
76   CORBA::String_var aComponentID(aSComponent->GetID());
77   CORBA::String_var aFatherID(aFather->GetID());
78   VISU::Result_var aResult;
79   while(strcmp(aComponentID,aFatherID) != 0){
80     CORBA::Object_var anObject = VISU::SObjectToObject(aFather);
81     if(!CORBA::is_nil(anObject)){
82       aResult = VISU::Result::_narrow(anObject);
83       if(!aResult->_is_nil()) return aResult;
84     }
85     aFather = aFather->GetFather();
86   }
87   return aResult;
88 }
89
90 void VISU::RemoveFromStudy (SALOMEDS::SObject_ptr theSObject,
91                             bool theIsAttrOnly,
92                             bool theDestroySubObjects)
93 {
94   if (theSObject->_is_nil()) return;
95
96   SALOMEDS::Study_var aStudyDocument = theSObject->GetStudy();
97   SALOMEDS::StudyBuilder_var aStudyBuilder = aStudyDocument->NewBuilder();
98   if (theIsAttrOnly) {
99     aStudyBuilder->RemoveAttribute(theSObject,"AttributeIOR");
100     return;
101   }
102
103   // Remove possible sub-objects
104   SALOMEDS::ChildIterator_var aChildIter = aStudyDocument->NewChildIterator(theSObject);
105   for (aChildIter->InitEx(true); aChildIter->More(); aChildIter->Next()) {
106     SALOMEDS::SObject_var aChildSObject = aChildIter->Value();
107     CORBA::Object_var aChildObj = VISU::SObjectToObject(aChildSObject);
108     if (CORBA::is_nil(aChildObj)) continue;
109
110     VISU::RemovableObject_var aRemovableObject = VISU::RemovableObject::_narrow(aChildObj);
111     if (CORBA::is_nil(aRemovableObject)) continue;
112
113     aRemovableObject->RemoveFromStudy();
114
115     // Destroy
116     if (theDestroySubObjects) {
117       VISU::Prs3d_var aPrs3d = VISU::Prs3d::_narrow(aRemovableObject);
118       if (CORBA::is_nil(aPrs3d)) continue;
119       aPrs3d->Destroy();
120     }
121   }
122
123   // Remove the SObject itself
124   aStudyBuilder->RemoveObjectWithChildren(theSObject);
125 }
126
127 QString GenerateName(const char* theName){
128   typedef map<string,int> TNameMap;
129   static TNameMap aMap;
130   TNameMap::const_iterator i = aMap.find(theName);
131   QString tmp;
132   if(i == aMap.end()) {
133     aMap[theName] = 0;
134     tmp = theName;
135   }else{
136     tmp = VISU::GenerateName(theName,++aMap[theName]);
137   }
138   if(MYDEBUG) MESSAGE("GenerateName - "<<tmp<<" from - "<<theName<<"; " <<aMap[theName]);
139   return tmp;
140 }
141
142 QString GenerateFieldName(const string& theName, const string& theUnits){
143   static QString aName;
144   const string tmp(theUnits.size(),' ');
145   if(theUnits == "" || theUnits == tmp)
146     aName.sprintf("%s, -",theName.c_str());
147   else
148     aName.sprintf("%s, %s",theName.c_str(),theUnits.c_str());
149   aName = aName.simplifyWhiteSpace();
150   return aName.latin1();
151 }
152
153 void CreateReference(SALOMEDS::Study_ptr theStudyDocument,
154                      const string& theFatherEntry, const string& theRefEntry)
155 {
156   SALOMEDS::StudyBuilder_var aStudyBuilder = theStudyDocument->NewBuilder();
157   SALOMEDS::SObject_var aFather = theStudyDocument->FindObjectID(theFatherEntry.c_str());
158   SALOMEDS::SObject_var newObj = aStudyBuilder->NewObject(aFather);
159   SALOMEDS::SObject_var aRefSObj = theStudyDocument->FindObjectID(theRefEntry.c_str());
160   aStudyBuilder->Addreference(newObj,aRefSObj);
161 }
162
163 string GetComponentDataType (SALOMEDS::SObject_ptr theSObject)
164 {
165   SALOMEDS::Study_var aStudy = theSObject->GetStudy();
166   SALOMEDS::SComponent_var aCompRefSObj = theSObject->GetFatherComponent();
167   CORBA::String_var aDataType = aCompRefSObj->ComponentDataType();
168   return aDataType.in();
169 }
170
171 //==============================================================================
172
173 const string VISU::Result_i::myComment = "RESULT";
174 const char* VISU::Result_i::GetComment() const { return myComment.c_str();}
175
176 VISU::Result_i::Result_i(SALOMEDS::Study_ptr theStudy,
177                          const ESourceId& theSourceId,
178                          const ECreationId& theCreationId):
179   myStudyDocument(SALOMEDS::Study::_duplicate(theStudy)),
180   myCreationId(theCreationId),
181   mySourceId(theSourceId),
182   myInput(NULL),
183   myIsDone(0)
184 {
185 }
186
187
188 void VISU::Result_i::RemoveFromStudy()
189 {
190   // Remove the result with all presentations and other possible sub-objects
191   VISU::RemoveFromStudy(mySObject,false);
192 }
193
194
195 int
196 VISU::Result_i::
197 IsPossible()
198 {
199   try{
200     float aSize = myInput->GetSize();
201     bool aResult = VISU_PipeLine::CheckAvailableMemory(aSize);
202     MESSAGE("Result_i::IsPossible - CheckAvailableMemory = "<<float(aSize)<<"; aResult = "<<float(aResult));
203     return aResult;
204   }catch(std::exception& exc){
205     INFOS("Follow exception was occured :\n"<<exc.what());
206   }catch(...){
207     INFOS("Unknown exception was occured!");
208   }
209   return 0;
210 }
211
212
213 CORBA::Boolean
214 VISU::Result_i::
215 BuildAll()
216 {
217   if(MYDEBUG) MESSAGE("Result_i::Build - myIsDone = "<<myIsDone);
218   if(myIsDone) return 1;
219   if(!IsPossible()) return 0;
220   try{
221     const VISU::TMeshMap& aMeshMap = myInput->GetMeshMap();
222     VISU::TMeshMap::const_iterator aMeshMapIter = aMeshMap.begin();
223     for(; aMeshMapIter != aMeshMap.end(); aMeshMapIter++){
224       const string& aMeshName = aMeshMapIter->first;
225       const VISU::PMesh aMesh = aMeshMapIter->second;
226       const VISU::TMeshOnEntityMap& aMeshOnEntityMap = aMesh->myMeshOnEntityMap;
227       VISU::TMeshOnEntityMap::const_iterator aMeshOnEntityMapIter;
228       //Import fields
229       aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
230       for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++){
231         const VISU::TEntity& anEntity = aMeshOnEntityMapIter->first;
232         const VISU::PMeshOnEntity aMeshOnEntity = aMeshOnEntityMapIter->second;
233         const VISU::TFieldMap& aFieldMap = aMeshOnEntity->myFieldMap;
234         VISU::TFieldMap::const_iterator aFieldMapIter = aFieldMap.begin();
235         for(; aFieldMapIter != aFieldMap.end(); aFieldMapIter++){
236           const string& aFieldName = aFieldMapIter->first;
237           const VISU::PField aField = aFieldMapIter->second;
238           const VISU::TValField& aValField = aField->myValField;
239           VISU::TValField::const_iterator aValFieldIter = aValField.begin();
240           for(; aValFieldIter != aValField.end(); aValFieldIter++){
241             int aTimeStamp = aValFieldIter->first;
242             try{
243               myInput->GetTimeStampOnMesh(aMeshName,anEntity,aFieldName,aTimeStamp);
244             }catch(std::exception& exc){
245               INFOS("Follow exception was occured :\n"<<exc.what());
246             }catch(...){
247               INFOS("Unknown exception was occured!!!");
248             }
249           }
250         }
251         //Importing groups
252         const VISU::TGroupMap& aGroupMap = aMesh->myGroupMap;
253         VISU::TGroupMap::const_iterator aGroupMapIter = aGroupMap.begin();
254         for(; aGroupMapIter != aGroupMap.end(); aGroupMapIter++){
255           const string& aGroupName = aGroupMapIter->first;
256           try{
257             myInput->GetMeshOnGroup(aMeshName,aGroupName);
258           }catch(std::exception& exc){
259             INFOS("Follow exception was occured :\n"<<exc.what());
260           }catch(...){
261             INFOS("Unknown exception was occured!!!");
262           }
263         }
264         //Import families
265         const VISU::TFamilyMap& aFamilyMap = aMeshOnEntity->myFamilyMap;
266         VISU::TFamilyMap::const_iterator aFamilyMapIter = aFamilyMap.begin();
267         for(; aFamilyMapIter != aFamilyMap.end(); aFamilyMapIter++){
268           const string& aFamilyName = aFamilyMapIter->first;
269           try{
270             myInput->GetMeshOnEntity(aMeshName,anEntity,aFamilyName);
271           }catch(std::exception& exc){
272             INFOS("Follow exception was occured :\n"<<exc.what());
273           }catch(...){
274             INFOS("Unknown exception was occured!!!");
275           }
276         }
277         //Import mesh on entity
278         try{
279           myInput->GetMeshOnEntity(aMeshName,anEntity);
280         }catch(std::exception& exc){
281           INFOS("Follow exception was occured :\n"<<exc.what());
282         }catch(...){
283           INFOS("Unknown exception was occured!!!");
284         }
285       }
286     }
287     myIsDone = 1;
288   }catch(std::exception& exc){
289     INFOS("Follow exception was occured :\n"<<exc.what());
290   }catch(...){
291     INFOS("Unknown exception was occured!!!");
292   }
293   return myIsDone;
294 }
295
296
297 VISU::Storable*
298 VISU::Result_i::
299 Build(SALOMEDS::SObject_ptr theSObject)
300 {
301   SALOMEDS::StudyBuilder_var aStudyBuilder = myStudyDocument->NewBuilder();
302   aStudyBuilder->NewCommand();  // There is a transaction
303   if(MYDEBUG) MESSAGE("Result_i::Build");
304   try{
305     const TMeshMap& aMeshMap = myInput->GetMeshMap();
306     if(aMeshMap.empty())
307       throw std::runtime_error("Build - There is no any mesh information in the file !!!");
308     mySComponent = FindOrCreateVisuComponent(myStudyDocument);
309     CORBA::String_var aSComponentEntry = mySComponent->GetID(), anIOR(GetID());
310     string aRefFatherEntry = GetRefFatherEntry();
311     QString aComment;
312     aComment.sprintf("myComment=%s;myType=%d;myFileName=%s;myInitFileName=%s",
313                      GetComment(),
314                      VISU::TRESULT,
315                      myFileInfo.filePath().latin1(),
316                      myInitFileName.c_str()); // Restoring of Python dump
317     string aResultEntry =
318       CreateAttributes(myStudyDocument,
319                        aSComponentEntry,
320                        aRefFatherEntry.c_str(),
321                        anIOR,
322                        myName.c_str(),
323                        "",
324                        aComment.latin1(),
325                        true);
326     mySObject = myStudyDocument->FindObjectID(aResultEntry.c_str());
327     if(mySObject->_is_nil()) throw std::runtime_error("Build - There is no SObject for the Result !!!");
328     if(!CORBA::is_nil(theSObject)){
329       CORBA::String_var aString = theSObject->GetID();
330       CreateReference(myStudyDocument,aResultEntry,aString.in());
331     }
332     TMeshMap::const_iterator aMeshMapIter = aMeshMap.begin();
333     for(; aMeshMapIter != aMeshMap.end(); aMeshMapIter++){
334       const string& aMeshName = aMeshMapIter->first;
335       const VISU::PMesh aMesh = aMeshMapIter->second;
336       const VISU::TMeshOnEntityMap& aMeshOnEntityMap = aMesh->myMeshOnEntityMap;
337       VISU::TMeshOnEntityMap::const_iterator aMeshOnEntityMapIter;
338       aComment.sprintf("myComment=MESH;myName=%s;myDim=%d",
339                        aMeshName.c_str(),aMesh->myDim);
340       string aMeshEntry = CreateAttributes(myStudyDocument,aResultEntry.c_str(),aRefFatherEntry.c_str(),
341                                            "",aMeshName.c_str(),"",aComment.latin1(),true);
342       if(aMeshOnEntityMap.empty()) continue;
343       aComment.sprintf("myComment=FAMILIES;myMeshName=%s",aMeshName.c_str());
344       string aSubMeshesEntry = CreateAttributes(myStudyDocument,aMeshEntry.c_str(),aRefFatherEntry.c_str(),
345                                                 "","Families","",aComment.latin1(),true);
346       //Import entities and according families
347       aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
348       typedef std::map<std::string,std::string> TComment2EntryMap;
349       TComment2EntryMap aComment2EntryMap;
350       typedef std::map<VISU::TEntity,std::string> TEntity2EntryMap;
351       TEntity2EntryMap aEntity2EntryMap;
352       for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++){
353         const VISU::TEntity& anEntity = aMeshOnEntityMapIter->first;
354         aComment.sprintf("myComment=ENTITY;myType=%d;myMeshName=%s;myId=%d",
355                          VISU::TENTITY,
356                          aMeshName.c_str(),
357                          anEntity);
358         string anEntityName;
359         switch(anEntity){
360         case VISU::NODE_ENTITY : anEntityName = "onNodes"; break;
361         case VISU::EDGE_ENTITY : anEntityName = "onEdges"; break;
362         case VISU::FACE_ENTITY : anEntityName = "onFaces"; break;
363         case VISU::CELL_ENTITY : anEntityName = "onCells"; break;
364         default:
365           throw std::runtime_error("Build >> Value of entity is incorrect!");
366         }
367         aEntity2EntryMap[anEntity] = CreateAttributes(myStudyDocument,aSubMeshesEntry.c_str(),aRefFatherEntry.c_str(),
368                                                    "",anEntityName.c_str(),"",aComment.latin1(),true);
369         const VISU::PMeshOnEntity aMeshOnEntity = aMeshOnEntityMapIter->second;
370         const VISU::TFamilyMap& aFamilyMap = aMeshOnEntity->myFamilyMap;
371         VISU::TFamilyMap::const_iterator aFamilyMapIter = aFamilyMap.begin();
372         for(; aFamilyMapIter != aFamilyMap.end(); aFamilyMapIter++){
373           const string& aFamilyName = aFamilyMapIter->first;
374           aComment.sprintf("myComment=FAMILY;myType=%d;myMeshName=%s;myEntityId=%d;myName=%s",
375                            VISU::TFAMILY,
376                            aMeshName.c_str(),
377                            anEntity,
378                            aFamilyName.c_str());
379           aComment2EntryMap[aComment.latin1()] =
380             CreateAttributes(myStudyDocument,
381                              aEntity2EntryMap[anEntity].c_str(),
382                              aRefFatherEntry.c_str(),
383                              "",
384                              aFamilyName.c_str(),
385                              "",
386                              aComment.latin1(),
387                              true);
388         }
389       }
390       //Importing groups
391       const VISU::TGroupMap& aGroupMap = aMesh->myGroupMap;
392       if(aGroupMap.size() > 0){
393         aComment.sprintf("myComment=GROUPS;myMeshName=%s",
394                          aMeshName.c_str());
395         string aGroupsEntry =
396           CreateAttributes(myStudyDocument,
397                            aMeshEntry.c_str(),
398                            aRefFatherEntry.c_str(),
399                            "",
400                            "Groups",
401                            "",
402                            aComment.latin1(),
403                            true);
404         VISU::TGroupMap::const_iterator aGroupMapIter = aGroupMap.begin();
405         for(; aGroupMapIter != aGroupMap.end(); aGroupMapIter++){
406           const string& aGroupName = aGroupMapIter->first;
407           aComment.sprintf("myComment=GROUP;myType=%d;myMeshName=%s;myName=%s",
408                            VISU::TGROUP,aMeshName.c_str(),aGroupName.c_str());
409           string aGroupEntry = CreateAttributes(myStudyDocument,aGroupsEntry.c_str(),aRefFatherEntry.c_str(),
410                                                 "",aGroupName.c_str(),"",aComment.latin1(),true);
411           const VISU::PGroup aGroup = aGroupMapIter->second;
412           const VISU::TFamilyAndEntitySet& aFamilyAndEntitySet = aGroup->myFamilyAndEntitySet;
413           VISU::TFamilyAndEntitySet::const_iterator aFamilyAndEntitySetIter = aFamilyAndEntitySet.begin();
414           for(; aFamilyAndEntitySetIter != aFamilyAndEntitySet.end(); aFamilyAndEntitySetIter++){
415             const VISU::TFamilyAndEntity& aFamilyAndEntity = *aFamilyAndEntitySetIter;
416             const string& aFamilyName = aFamilyAndEntity.first;
417             const VISU::TEntity& anEntity = aFamilyAndEntity.second;
418             aComment.sprintf("myComment=FAMILY;myType=%d;myMeshName=%s;myEntityId=%d;myName=%s",
419                              VISU::TFAMILY,
420                              aMeshName.c_str(),
421                              anEntity,
422                              aFamilyName.c_str());
423             CreateReference(myStudyDocument,aGroupEntry,aComment2EntryMap[aComment.latin1()]);
424           }
425         }
426       }
427       //Import fields
428       string aFieldsEntry;
429       bool isFieldEntryCreated = 0;
430       aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
431       for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++){
432         const VISU::TEntity& anEntity = aMeshOnEntityMapIter->first;
433         const VISU::PMeshOnEntity aMeshOnEntity = aMeshOnEntityMapIter->second;
434         const VISU::TFieldMap& aFieldMap = aMeshOnEntity->myFieldMap;
435         VISU::TFieldMap::const_iterator aFieldMapIter = aFieldMap.begin();
436         for(; aFieldMapIter != aFieldMap.end(); aFieldMapIter++){
437           if(!isFieldEntryCreated){
438             aComment.sprintf("myComment=FIELDS;myMeshName=%s",
439                              aMeshName.c_str());
440             aFieldsEntry =
441               CreateAttributes(myStudyDocument,
442                                aMeshEntry.c_str(),
443                                aRefFatherEntry.c_str(),
444                                "",
445                                "Fields",
446                                "",
447                                aComment.latin1(),
448                                true);
449             isFieldEntryCreated = true;
450           }
451           const string& aFieldName = aFieldMapIter->first;
452           const VISU::PField aField = aFieldMapIter->second;
453           const VISU::TValField& aValField = aField->myValField;
454           QString aFieldNameWithUnit = ::GenerateFieldName(aFieldName,aField->myUnitNames[0]);
455           aComment.sprintf("myComment=FIELD;myType=%d;myMeshName=%s;myEntityId=%d;myName=%s;myNbTimeStamps=%d;myNumComponent=%d",
456                            VISU::TFIELD,aMeshName.c_str(),anEntity,aFieldName.c_str(),aValField.size(),aField->myNbComp);
457           string aFieldEntry = CreateAttributes(myStudyDocument,aFieldsEntry.c_str(),aRefFatherEntry.c_str(),
458                                                 "",aFieldNameWithUnit.latin1(),"",aComment.latin1(),true);
459           CreateReference(myStudyDocument,aFieldEntry,aEntity2EntryMap[anEntity]);
460           VISU::TValField::const_iterator aValFieldIter = aValField.begin();
461           for(; aValFieldIter != aValField.end(); aValFieldIter++){
462             int aTimeStamp = aValFieldIter->first;
463             const VISU::PValForTime aValForTime = aValFieldIter->second;
464             aComment.sprintf("myComment=TIMESTAMP;myType=%d;myMeshName=%s;myEntityId=%d;myFieldName=%s;myTimeStampId=%d;myNumComponent=%d",
465                              VISU::TTIMESTAMP,aMeshName.c_str(),anEntity,aFieldName.c_str(),aTimeStamp,aField->myNbComp);
466             string aTimeStampId = VISU_Convertor::GenerateName(aValForTime->myTime);
467             CreateAttributes(myStudyDocument,aFieldEntry.c_str(),aRefFatherEntry.c_str(),
468                              "",aTimeStampId.c_str(),"",aComment.latin1(),true);
469           }
470         }
471       }
472     }
473     QString aIsBuild = VISU::GetResourceMgr()->stringValue("Visu:BuildResult");
474     bool isBuildAll = aIsBuild.isEmpty()? 0 : aIsBuild.toInt();
475     if(isBuildAll) BuildAll();
476   }catch(std::exception& exc){
477     INFOS("Follow exception was occured :\n"<<exc.what());
478     return NULL;
479   }catch(...){
480     INFOS("Unknown exception was occured!!!");
481     return NULL;
482   }
483   aStudyBuilder->CommitCommand();
484   return this;
485 }
486
487
488 VISU::Storable*
489 VISU::Result_i::
490 Create(const char* theFileName)
491 {
492   try{
493     myFileInfo.setFile(theFileName);
494     myInitFileName = myFileInfo.filePath().latin1();
495     myName = ::GenerateName(myFileInfo.fileName()).latin1();
496     if(mySourceId == eRestoredFile){
497       std::string aTmpDir(SALOMEDS_Tool::GetTmpDir());
498       static QString aCommand;
499       aCommand.sprintf("cp %s %s",myFileInfo.absFilePath().latin1(),aTmpDir.c_str());
500       if(system(aCommand) == -1){
501         MESSAGE("Create - Can't execute the command :"<<aCommand);
502         return NULL;
503       }
504       if(MYDEBUG) MESSAGE("Result_i::Create - aCommand = "<<aCommand);
505       myFileInfo.setFile(QString(aTmpDir.c_str()) + myFileInfo.fileName());
506     }
507     myInput = CreateConvertor(myFileInfo.absFilePath().latin1());
508     if(!myInput)
509       throw std::runtime_error("Create - Cannot create a Convertor for this file!!!"); return Build();
510   }catch(std::exception& exc){
511     INFOS("Follow exception was occured :\n"<<exc.what());
512   }catch(...){
513     INFOS("Unknown exception was occured!!!");
514   }
515   return NULL;
516 }
517
518
519 VISU::Storable*
520 VISU::Result_i::
521 Create(SALOMEDS::SObject_ptr theMedSObject)
522 {
523   if(MYDEBUG)  MESSAGE("Result_i::Create MedObject from SALOMEDS::SObject_ptr");
524   try{
525     myInput = CreateMEDConvertor(theMedSObject);
526     if(myInput == NULL)
527       return NULL;
528
529     string aCompDataType = GetComponentDataType(theMedSObject);
530     myFileInfo.setFile(aCompDataType.c_str());
531     myInitFileName = aCompDataType;
532
533     myName = ::GenerateName("aResult").latin1();
534
535     VISU::Storable* aStorable = Build(theMedSObject);
536     return aStorable;
537   }catch(std::exception& exc){
538     INFOS("Follow exception was occured :\n"<<exc.what());
539   }catch(...){
540     INFOS("Unknown exception was occured!!!");
541   }
542   return NULL;
543 }
544
545 VISU::Storable*
546 VISU::Result_i::
547 Create(SALOME_MED::FIELD_ptr theField)
548 {
549   if(MYDEBUG)  MESSAGE("Result_i::Create MedObject from SALOME_MED::FIELD_ptr");
550   try{
551     myInput = CreateMEDFieldConvertor(theField);
552     if(myInput == NULL)
553       return NULL;
554
555     string aCompDataType = "MED";
556     myFileInfo.setFile(aCompDataType.c_str());
557     myInitFileName = aCompDataType;
558
559     myName = ::GenerateName("aResult").latin1();
560
561     CORBA::String_var anIOR = myStudyDocument->ConvertObjectToIOR(theField);
562     SALOMEDS::SObject_var aFieldSObject = myStudyDocument->FindObjectIOR(anIOR);
563
564     VISU::Storable* aStorable = Build(aFieldSObject);
565     return aStorable;
566   }catch(std::exception& exc){
567     INFOS("Follow exception was occured :\n"<<exc.what());
568   }catch(...){
569     INFOS("Unknown exception was occured!!!");
570   }
571   return NULL;
572 }
573
574
575 VISU::Storable*
576 VISU::Result_i::
577 Restore(SALOMEDS::SObject_ptr theSObject,
578         const Storable::TRestoringMap& theMap,
579         const string& thePrefix)
580 {
581   if(MYDEBUG)  MESSAGE("Result_i::Restore - "<<thePrefix);
582   try{
583     mySObject = SALOMEDS::SObject::_duplicate(theSObject);
584     myStudyDocument = mySObject->GetStudy();
585     mySComponent = mySObject->GetFatherComponent();
586     myName = VISU::Storable::FindValue(theMap,"myName").latin1();
587     myInitFileName = VISU::Storable::FindValue(theMap,"myInitFileName").latin1();
588     SALOMEDS::SObject_var aRefSObj, aTargetRefSObj;
589     if(mySObject->FindSubObject(1,aRefSObj) && aRefSObj->ReferencedObject(aTargetRefSObj)){
590       if(MYDEBUG)  MESSAGE("Result_i::GetInput - There is some reference.");
591       SALOMEDS::SComponent_var aCompRefSObj = aTargetRefSObj->GetFatherComponent();
592       CORBA::String_var aDataType = aCompRefSObj->ComponentDataType();
593       myFileInfo.setFile(aDataType.in());
594       if(MYDEBUG)  MESSAGE("Result_i::GetInput - aDataType = "<<aDataType);
595       Engines::Component_var aEngComp = Base_i::myEnginesLifeCycle->FindOrLoad_Component("FactoryServer", aDataType.in());
596       if (CORBA::is_nil(aEngComp))
597         throw std::runtime_error("Restore - There is no aEngComp for the aDataType !!!");
598       SALOMEDS::StudyBuilder_var  aStudyBuilder = myStudyDocument->NewBuilder();
599       SALOMEDS::Driver_var aDriver = SALOMEDS::Driver::_narrow(aEngComp);
600       aStudyBuilder->LoadWith(aCompRefSObj,aDriver);
601       if(strcmp(aDataType,"MED") == 0)
602         myInput = CreateMEDConvertor(aTargetRefSObj);
603       else
604         throw std::runtime_error("GetInput - There is no convertor for the aDataType !!!");
605     }else{
606       myFileInfo.setFile(thePrefix.c_str());
607
608       string aStudyPrefix("");
609       if (IsMultifile()) aStudyPrefix = (SALOMEDS_Tool::GetNameFromPath(myStudyDocument->URL()));
610       if(!myFileInfo.isFile()){
611         string aFileName = thePrefix + aStudyPrefix + "_" + myName;
612         myFileInfo.setFile(aFileName.c_str());
613       }
614       if(MYDEBUG)
615         MESSAGE("Result_i::Restore - aFileName = "<<myFileInfo.filePath()<<"; "<<myFileInfo.isFile());
616
617       if (HDFascii::isASCII(myFileInfo.filePath().latin1())) {
618         char* aResultPath = HDFascii::ConvertFromASCIIToHDF(myFileInfo.filePath().latin1());
619         char* aHDFFileName = new char[strlen(aResultPath) + 19];
620         sprintf(aHDFFileName, "%shdf_from_ascii.hdf", aResultPath);
621
622         if (IsMultifile()) { // set this file as new - temporary
623           static QString aCommand;
624           aCommand.sprintf("mv %s %s%s",aHDFFileName, aResultPath, myFileInfo.baseName().latin1());
625           if(system(aCommand) == -1){
626             if(MYDEBUG) MESSAGE("VISU::Result_i::Restore - Can't execute the command :"<<aCommand);
627             return NULL;
628           } else if(MYDEBUG) MESSAGE("VISU::Result_i::Restore - "<<aCommand);
629           myFileInfo.setFile(QString(aResultPath)+QString(myFileInfo.baseName().latin1()));
630         } else { // change current temporary file to the new: with hdf-format
631           static QString aCommand;
632           aCommand.sprintf("mv %s %s\0",aHDFFileName, myFileInfo.filePath().latin1());
633           if(system(aCommand.latin1()) == -1) {
634             if(MYDEBUG) MESSAGE("VISU::Result_i::Restore - Can't execute the command :"<<aCommand);
635             return NULL;
636           } else if(MYDEBUG) MESSAGE("VISU::Result_i::Restore - "<<aCommand);
637           SALOMEDS::ListOfFileNames_var anEmptyList = new SALOMEDS::ListOfFileNames;
638           SALOMEDS_Tool::RemoveTemporaryFiles(aResultPath, anEmptyList.in(), true);
639         }
640         mySourceId = eRestoredFile;
641         delete(aResultPath);
642         delete(aHDFFileName);
643       } else if (!IsMultifile())
644         mySourceId = eRestoredFile;
645       else
646         mySourceId = eFile;
647       if(MYDEBUG) MESSAGE("VISU::Result_i::Restore - mySourceId = "<<mySourceId);
648       myInput = CreateConvertor(myFileInfo.filePath().latin1());
649       QString aComment;
650       aComment.sprintf("myComment=%s;myType=%d;myFileName=%s;myInitFileName=%s",
651                        GetComment(),VISU::TRESULT,myFileInfo.filePath().latin1(),
652                        myInitFileName.c_str()); // Restoring of Python dump
653       SALOMEDS::GenericAttribute_var anAttr;
654       if(!theSObject->FindAttribute(anAttr, "AttributeComment"))
655         throw std::runtime_error("Build - There is no AttributeComment for the SObject !!!");
656       SALOMEDS::AttributeComment_var aCmnt = SALOMEDS::AttributeComment::_narrow(anAttr);
657       aCmnt->SetValue(aComment.latin1());
658     }
659     QString aIsBuild = VISU::GetResourceMgr()->stringValue("Visu:BuildResult");
660     if(aIsBuild.isEmpty()? 0 : aIsBuild.toInt())
661       BuildAll();
662     return this;
663   }catch(std::exception& exc){
664     INFOS("Follow exception was occured :\n"<<exc.what());
665   }catch(...){
666     INFOS("Unknown exception was occured!!!");
667   }
668   return NULL;
669 }
670
671 VISU::Result_i::TInput* VISU::Result_i::GetInput() {
672   return myInput;
673 }
674
675 void VISU::Result_i::ToStream(std::ostringstream& theStr){
676   if(MYDEBUG) MESSAGE(GetComment());
677   Storable::DataToStream(theStr,"myName",myName.c_str());
678   Storable::DataToStream(theStr,"myInitFileName",myInitFileName.c_str());
679   Storable::DataToStream(theStr,"myCreationId",myCreationId);
680 }
681
682 VISU::Storable*
683 VISU::Result_i::Restore(SALOMEDS::SObject_ptr theSObject,
684                         const string& thePrefix,
685                         const Storable::TRestoringMap& theMap)
686 {
687   SALOMEDS::Study_var aStudy = theSObject->GetStudy();
688
689   ECreationId aCreationId = ECreationId(Storable::FindValue(theMap,"myCreationId").toInt());
690   ESourceId aSourceId = eRestoredFile;
691   if(aCreationId == eImportMed || aCreationId == eImportMedField)
692     aSourceId = eRestoredComponent;
693
694   VISU::Result_i* pResult = new VISU::Result_i(aStudy,aSourceId,aCreationId);
695   if(pResult == NULL)
696     return NULL;
697
698   return pResult->Restore(theSObject,theMap,thePrefix);
699 }
700
701 string VISU::Result_i::GetRefFatherEntry() {
702   //return QAD_Application::getDesktop()->getActiveStudy()->getActiveStudyFrame()->entry();
703   return "";
704 }
705
706 string VISU::Result_i::GetEntry(){
707   CORBA::String_var anEntry = mySObject->GetID();
708   return string(anEntry);
709 }
710
711 const SALOMEDS::SObject_var& VISU::Result_i::GetSObject() const { return mySObject;}
712 const SALOMEDS::Study_var& VISU::Result_i::GetStudyDocument() const { return myStudyDocument;}
713 const SALOMEDS::SComponent_var& VISU::Result_i::GetSComponent() const { return mySComponent;}
714 std::string VISU::Result_i::GetEntry(const std::string& theComment)
715 {
716   return FindEntryWithComment(myStudyDocument,GetEntry().c_str(),theComment.c_str());
717 }
718
719 VISU::Result_i::~Result_i() {
720   MESSAGE("Result_i::~Result_i() - this = "<<this);
721   if(mySourceId == eRestoredFile){
722     static QString aCommand;
723     aCommand.sprintf("rm %s",myFileInfo.filePath().latin1());
724     MESSAGE("Result_i::~Result_i - system("<<aCommand<<") = "<<system(aCommand));
725     aCommand.sprintf("rmdir --ignore-fail-on-non-empty %s",myFileInfo.dirPath().latin1());
726     MESSAGE("Result_i::~Result_i - system("<<aCommand<<") = "<<system(aCommand));
727   }
728   if(myInput) delete myInput;
729 }
730
731 //=======================================================================
732 //function : GetAxisInfo
733 //purpose  :
734 //=======================================================================
735 const vector< float >* Result_i::GetAxisInfo(const string& theMeshName,
736                                              TAxis         theAxis,
737                                              gp_Dir&       thePlaneNormal)
738 {
739   const vector< float >* components = NULL;
740
741   if ( theAxis < AXIS_X || theAxis > AXIS_Z ) {
742     MESSAGE(" Bad axis index " << theAxis );
743     return components;
744   }
745
746   map< string, TGridInfo >::iterator name_info;
747   name_info = myMeshName2GridInfoMap.find( theMeshName );
748   TGridInfo * gInfo = 0;
749
750   if ( name_info != myMeshName2GridInfoMap.end() )
751   {
752     gInfo = & name_info->second;
753   }
754   else if ( myInput && IsPossible() && theAxis >= AXIS_X && theAxis <= AXIS_Z )
755   {
756     // check presence of theMeshName
757     const VISU::TMeshMap& meshMap = myInput->GetMeshMap();
758     if ( meshMap.find( theMeshName ) == meshMap.end() ) {
759       MESSAGE("No mesh named " << theMeshName );
760       return components;
761     }
762     VISU_Convertor::TOutput* vtkMesh = myInput->GetMeshOnEntity (theMeshName,
763                                                                  CELL_ENTITY);
764     if ( !vtkMesh || vtkMesh->GetNumberOfCells() == 0 ) {
765       MESSAGE( "No cells in the mesh: " << theMeshName );
766       return components;
767     }
768
769     // define axis directions and min cell size in each direction
770     const int nbAxes = 3;
771     int iAx;
772     gp_Vec axDirs[ nbAxes ];
773     float minSize[3] = { FLT_MAX, FLT_MAX, FLT_MAX };
774     bool axesComputed = false;
775     for ( vtkIdType iCell = 0; iCell < vtkMesh->GetNumberOfCells(); ++iCell )
776     {
777       vtkCell* cell = vtkMesh->GetCell( iCell );
778       int nbPnt = cell->GetNumberOfPoints();
779       if ( nbPnt != 8 )
780         continue;
781       vtkPoints * points = cell->GetPoints();
782       float* coords[ 4 ];
783       coords[0] = points->GetPoint( 0 );
784       coords[1] = points->GetPoint( 1 );
785       coords[2] = points->GetPoint( 3 );
786       coords[3] = points->GetPoint( 4 );
787       gp_Pnt p0( coords[0][0], coords[0][1], coords[0][2] );
788       for ( iAx = 0; iAx < nbAxes; ++iAx )
789       {
790         float* coo = coords[ iAx + 1 ];
791         gp_Pnt p( coo[0], coo[1], coo[2] );
792         // min size
793         float size = p0.SquareDistance( p );
794         if ( size > FLT_MIN && size < minSize[ iAx ] )
795           minSize[ iAx ] = size;
796         // axis direction
797         if ( !axesComputed ) {
798           gp_Vec dir( p0, p );
799           if ( dir.SquareMagnitude() <= DBL_MIN )
800             break;
801           axDirs[ iAx ] = dir;
802         }
803       }
804       if ( iAx == nbAxes )
805         axesComputed = true;
806     }
807     if ( !axesComputed ) {
808       MESSAGE("No good hexahedrons in the mesh: " << theMeshName );
809       return components;
810     }
811
812     // compute axes dirs
813     gInfo = & myMeshName2GridInfoMap[ theMeshName ];
814     for ( iAx = 0; iAx < nbAxes; ++iAx )
815     {
816       int iPrev = ( iAx == 0 ) ? 2 : iAx - 1;
817       int iNext = ( iAx == 2 ) ? 0 : iAx + 1;
818       gInfo->myAxis[ iAx ] = axDirs[ iPrev ] ^ axDirs[ iNext ];
819     }
820
821     // get and sort intermediate component values - projections of nodes
822     // on axis direction; define bnd box
823     set< float > comps[ 3 ];
824     Bnd_Box box;
825     vtkPoints * points = vtkMesh->GetPoints();
826     vtkIdType iP, nbP = vtkMesh->GetNumberOfPoints();
827     for ( iP = 0; iP < nbP; ++iP )
828     {
829       float* coo = points->GetPoint( iP );
830       gp_Pnt p( coo[0], coo[1], coo[2] );
831       box.Add( p );
832       for ( iAx = 0; iAx < nbAxes; ++iAx ) {
833         const gp_Dir& dir = gInfo->myAxis[ iAx ];
834         float dot = dir.XYZ() * p.XYZ();
835         comps[ iAx ].insert( dot );
836       }
837     }
838
839     // find a range of projections of bnd box corners on each axis
840     float range[3], firstValue[3];
841     double x[2],y[2],z[2];
842     box.Get(x[0],y[0],z[0],x[1],y[1],z[1]);
843     for ( iAx = 0; iAx < nbAxes; ++iAx ) {
844       set< float > bndComps;
845       const gp_Dir& dir = gInfo->myAxis[ iAx ];
846       for ( int iX = 0; iX < 2; ++iX ) {
847         for ( int iY = 0; iY < 2; ++iY ) {
848           for ( int iZ = 0; iZ < 2; ++iZ ) {
849             gp_Pnt p( x[ iX ], y[ iY ], z[ iZ ] );
850             float dot = dir.XYZ() * p.XYZ();
851             bndComps.insert( dot );
852           }
853         }
854       }
855       firstValue[ iAx ] = *bndComps.begin();
856       range[ iAx ] = *bndComps.rbegin() - *bndComps.begin();
857     }
858
859     // compute component values
860     for ( iAx = 0; iAx < nbAxes; ++iAx )
861     {
862       list< float > values;
863       int nbVals = 0;
864       set< float >& comp = comps[ iAx ];
865       set< float >::iterator val = comp.begin();
866       float bnd = -1., rng = range[ iAx ], first = firstValue[ iAx ];
867       float tol = 0.1 * sqrt( minSize[ iAx ]) / rng;
868       for ( ; val != comp.end(); ++val ) {
869         float value = ( *val - first ) / rng;
870         if ( value > bnd ) {
871           values.push_back( value );
872           bnd = value + tol;
873           nbVals++;
874         }
875       }
876       // store values in gInfo
877       vector< float >& myComp = gInfo->myComponets[ iAx ];
878       myComp.resize( nbVals );
879       list< float >::iterator v = values.begin();
880       for ( int i = 0; v != values.end(); ++v )
881         myComp[ i++ ] = *v;
882     }
883   }
884
885   // set return values
886   if ( gInfo )
887   {
888     thePlaneNormal = gInfo->myAxis[ theAxis ];
889     components = & gInfo->myComponets[ theAxis ];
890   }
891
892   return components;
893 }