Salome HOME
2a85df8166ad105511b8a8743bca50ed8d1e1c30
[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_Convertor_impl.hxx"
30 #include "VISU_CorbaMedConvertor.hxx"
31 #include "VISU_ConvertorUtils.hxx"
32 #include "VISU_PipeLine.hxx"
33
34 #include "SUIT_ResourceMgr.h"
35
36 #include "SALOMEDS_Tool.hxx"
37 #include "HDFascii.hxx"
38
39 #include "SUIT_Session.h"
40 #include "SALOME_Event.hxx"
41 #include "SalomeApp_Study.h"
42 #include "SalomeApp_Application.h"
43
44 #include <boost/thread/recursive_mutex.hpp>
45 #include <boost/thread/thread.hpp>
46
47 #include <boost/thread/mutex.hpp>
48 #include <boost/bind.hpp>
49
50 // QT Includes
51 #include <qstring.h>
52 #include <qfileinfo.h>
53 #include <qsemaphore.h>
54 #include <qthread.h>
55
56 // VTK Includes
57 #include <vtkCell.h>
58 #include <vtkUnstructuredGrid.h>
59
60 // OCCT Includes
61 #include <Bnd_Box.hxx>
62
63 using namespace VISU;
64 using namespace std;
65
66 #ifdef _DEBUG_
67 static int MYDEBUG = 0;
68 static int MYTIMEDEBUG = 0;
69 #else
70 static int MYDEBUG = 0;
71 static int MYTIMEDEBUG = 0;
72 #endif
73
74
75 namespace VISU
76 {
77   //---------------------------------------------------------------
78   Result_var 
79   FindResult (SALOMEDS::SObject_ptr theSObject)
80   {
81     SALOMEDS::SComponent_var aSComponent = theSObject->GetFatherComponent();
82     SALOMEDS::SObject_var aFather = theSObject->GetFather();
83     CORBA::String_var aComponentID (aSComponent->GetID());
84     CORBA::String_var aFatherID    (aFather->GetID());
85     Result_var aResult;
86     while (strcmp(aComponentID, aFatherID) != 0) {
87       CORBA::Object_var anObject = SObjectToObject(aFather);
88       if (!CORBA::is_nil(anObject)) {
89         aResult = Result::_narrow(anObject);
90         if (!aResult->_is_nil()) return aResult;
91       }
92       aFather = aFather->GetFather();
93       aFatherID = aFather->GetID();
94     }
95     return aResult;
96   }
97
98
99   //---------------------------------------------------------------
100   typedef boost::recursive_mutex TMutex;
101   typedef TMutex::scoped_lock TLock;
102
103   static TMutex myMutex;
104
105   //---------------------------------------------------------------
106   struct TGetStudy: public SALOME_Event
107   {
108     typedef _PTR(Study) TResult;
109     TResult myResult;
110     int myStudyId;
111
112     TGetStudy(const int theStudyId):
113       myStudyId(theStudyId)
114     {}
115     
116     virtual
117     void
118     Execute()
119     {
120       SUIT_Session* aSession = SUIT_Session::session();
121       QPtrList<SUIT_Application> anApplications = aSession->applications();
122       QPtrListIterator<SUIT_Application> anIter (anApplications);
123       while (SUIT_Application* aSApp = anIter.current()) {
124         if(SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>(aSApp)){
125           if(SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(anApp->activeStudy())) {
126             if(_PTR(Study) aStudyDS = aStudy->studyDS()){
127               if(aStudyDS->StudyId() == myStudyId){
128                 myResult = aStudy->studyDS();
129                 break;
130               }
131             }
132           }
133         }
134         ++anIter;
135       }
136     }
137   };
138
139
140   //---------------------------------------------------------------
141   QString
142   GenerateName (const char* theName)
143   {
144     TLock aLock(myMutex);
145
146     typedef map<string,int> TNameMap;
147     static TNameMap aMap;
148
149     TNameMap::const_iterator i = aMap.find(theName);
150     QString tmp;
151     if (i == aMap.end()) {
152       aMap[theName] = 0;
153       tmp = theName;
154     } else {
155       tmp = GenerateName(theName,++aMap[theName]);
156     }
157     if(MYDEBUG) MESSAGE("GenerateName - "<<tmp<<" from - "<<theName<<"; " <<aMap[theName]);
158     return tmp;
159   }
160   
161
162   //---------------------------------------------------------------
163   QString 
164   GenerateFieldName (const string& theName, const string& theUnits)
165   {
166     QString aName;
167     const string tmp (theUnits.size(),' ');
168     if (theUnits == "" || theUnits == tmp)
169       aName.sprintf("%s, -",theName.c_str());
170     else
171       aName.sprintf("%s, %s",theName.c_str(),theUnits.c_str());
172     aName = aName.simplifyWhiteSpace();
173     return aName.latin1();
174   }
175
176
177   //---------------------------------------------------------------
178   string
179   GetComponentDataType (SALOMEDS::SObject_ptr theSObject)
180   {
181     SALOMEDS::SComponent_var aCompRefSObj = theSObject->GetFatherComponent();
182     CORBA::String_var aDataType = aCompRefSObj->ComponentDataType();
183     return aDataType.in();
184   }
185
186
187   //---------------------------------------------------------------
188   void
189   CreateReference (SALOMEDS::Study_ptr theStudyDocument,
190                    const string& theFatherEntry, 
191                    const string& theRefEntry)
192   {
193     SALOMEDS::StudyBuilder_var aStudyBuilder = theStudyDocument->NewBuilder();
194     SALOMEDS::SObject_var aFather = theStudyDocument->FindObjectID(theFatherEntry.c_str());
195     SALOMEDS::SObject_var newObj = aStudyBuilder->NewObject(aFather);
196     SALOMEDS::SObject_var aRefSObj = theStudyDocument->FindObjectID(theRefEntry.c_str());
197     aStudyBuilder->Addreference(newObj,aRefSObj);
198   }
199
200
201   //---------------------------------------------------------------
202   void
203   CreateReference (_PTR(Study) theStudyDocument,
204                    const string& theFatherEntry, 
205                    const string& theRefEntry)
206   {
207     TLock aLock(myMutex);
208
209     _PTR(StudyBuilder) aStudyBuilder = theStudyDocument->NewBuilder();
210     _PTR(SObject) aFather = theStudyDocument->FindObjectID(theFatherEntry);
211     _PTR(SObject) aNewObj = aStudyBuilder->NewObject(aFather);
212     _PTR(SObject) aRefSObj = theStudyDocument->FindObjectID(theRefEntry);
213     aStudyBuilder->Addreference(aNewObj,aRefSObj);
214   }
215
216   string 
217   CreateAttributes(_PTR(Study) theStudyDocument,
218                    const string& theFatherEntry, 
219                    const string& theIOR, 
220                    const string& theName,
221                    const string& thePersistentRef, 
222                    const string& theComment,
223                    CORBA::Boolean theCreateNew)
224   {
225     TLock aLock(myMutex);
226
227     _PTR(StudyBuilder) aStudyBuilder = theStudyDocument->NewBuilder();
228     _PTR(SObject) aFather = theStudyDocument->FindObjectID(theFatherEntry);
229
230     _PTR(SObject) aNewObj;
231     if(theCreateNew)
232       aNewObj = aStudyBuilder->NewObject(aFather);
233     else
234       aNewObj = aFather;
235
236     _PTR(GenericAttribute) anAttr;
237     if (theIOR != "") {
238       anAttr = aStudyBuilder->FindOrCreateAttribute(aNewObj, "AttributeIOR");
239       _PTR(AttributeIOR) anIOR (anAttr);
240       anIOR->SetValue(theIOR);
241     }
242     if (theName != "") {
243       anAttr = aStudyBuilder->FindOrCreateAttribute(aNewObj, "AttributeName");
244       _PTR(AttributeName) aName (anAttr);
245       aName->SetValue(theName);
246     }
247     if (thePersistentRef != "") {
248       anAttr = aStudyBuilder->FindOrCreateAttribute(aNewObj, "AttributePersistentRef");
249       _PTR(AttributePersistentRef) aPRef (anAttr);
250       aPRef->SetValue(thePersistentRef);
251     }
252     if (theComment != "") {
253       anAttr = aStudyBuilder->FindOrCreateAttribute(aNewObj, "AttributeComment");
254       _PTR(AttributeComment) aCmnt (anAttr);
255       aCmnt->SetValue(theComment);
256     }
257     return aNewObj->GetID();
258   }
259
260   //---------------------------------------------------------------
261   struct TResultManager
262   {
263     Result_i* myResult;
264
265     TResultManager(Result_i* theResult):
266       myResult(theResult)
267     {
268       myResult->Register();
269     }
270
271     ~TResultManager()
272     {
273       myResult->Destroy();
274     }
275   };
276
277
278   //---------------------------------------------------------------
279   struct TTransactionManager
280   {
281     _PTR(StudyBuilder) myStudyBuilder;
282
283     TTransactionManager(_PTR(Study) theStudyDocument):
284       myStudyBuilder(theStudyDocument->NewBuilder())
285     {
286       TLock aLock(myMutex);
287       myStudyBuilder->NewCommand();
288     }
289
290     ~TTransactionManager()
291     {
292       TLock aLock(myMutex);
293       myStudyBuilder->CommitCommand();
294     }
295   };
296
297
298   //---------------------------------------------------------------
299   struct TUpdateObjBrowser: public SALOME_Event
300   {
301     int myStudyId;
302     CORBA::Boolean* myIsDone;
303     TUpdateObjBrowser(const int theStudyId,
304                       CORBA::Boolean* theIsDone):
305       myStudyId(theStudyId),
306       myIsDone(theIsDone)
307     {}
308     
309     virtual
310     void
311     Execute()
312     {
313       TLock aLock(myMutex);
314       SUIT_Session* aSession = SUIT_Session::session();
315       QPtrList<SUIT_Application> anApplications = aSession->applications();
316       QPtrListIterator<SUIT_Application> anIter (anApplications);
317       while (SUIT_Application* aSApp = anIter.current()) {
318         if(SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>(aSApp)){
319           if (SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(anApp->activeStudy())) {
320             if (_PTR(Study) aCStudy = aStudy->studyDS()) {
321               if (myStudyId == aCStudy->StudyId()) {
322                 TTimerLog aTimerLog(MYTIMEDEBUG,"Result_i::updateObjectBrowser");
323                 anApp->updateObjectBrowser();
324                 *myIsDone = true;
325                 break;
326               }
327             }
328           }
329         }
330         ++anIter;
331       }
332     }
333   };
334
335
336   //---------------------------------------------------------------
337   void
338   BuildEntities(Result_i* theResult,
339                 VISU_Convertor* theInput,
340                 CORBA::Boolean* theIsDone,
341                 std::string theResultEntry,
342                 _PTR(Study) theStudy)
343   {
344     if(*theIsDone)
345       return;
346
347     TTimerLog aTimerLog(MYTIMEDEBUG,"Result_i::BuildEntities");
348     TResultManager aResultManager(theResult);
349     TTransactionManager aTransactionManager(theStudy);
350
351     {
352       TTimerLog aTimerLog(MYTIMEDEBUG,"theInput->BuildEntities");
353       theInput->BuildEntities();
354     }
355
356     QString aComment;
357     const TMeshMap& aMeshMap = theInput->GetMeshMap();
358     TMeshMap::const_iterator aMeshMapIter = aMeshMap.begin();
359     for(; aMeshMapIter != aMeshMap.end(); aMeshMapIter++){
360       const string& aMeshName = aMeshMapIter->first;
361       const PMesh& aMesh = aMeshMapIter->second;
362       const TMeshOnEntityMap& aMeshOnEntityMap = aMesh->myMeshOnEntityMap;
363       if(aMeshOnEntityMap.empty()) 
364         continue;
365     
366       aComment.sprintf("myComment=MESH;myName=%s;myDim=%d",
367                        aMeshName.c_str(),
368                        aMesh->myDim);
369       aMesh->myEntry = 
370         CreateAttributes(theStudy,
371                          theResultEntry,
372                          "",
373                          aMeshName,
374                          "",
375                          aComment.latin1(),
376                          true);
377     
378       aComment.sprintf("myComment=FAMILIES;myMeshName=%s",
379                        aMeshName.c_str());
380       string aSubMeshesEntry = 
381         CreateAttributes(theStudy,
382                          aMesh->myEntry,
383                          "",
384                          "Families",
385                          "",
386                          aComment.latin1(),
387                          true);
388       //Import entities
389       TMeshOnEntityMap::const_iterator aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
390       for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++){
391         const TEntity& anEntity = aMeshOnEntityMapIter->first;
392         const PMeshOnEntity& aMeshOnEntity = aMeshOnEntityMapIter->second;
393         
394         string anEntityName;
395         switch(anEntity){
396         case NODE_ENTITY: 
397           anEntityName = "onNodes"; 
398           break;
399         case EDGE_ENTITY: 
400           anEntityName = "onEdges"; 
401           break;
402         case FACE_ENTITY: 
403           anEntityName = "onFaces"; 
404           break;
405         case CELL_ENTITY: 
406           anEntityName = "onCells"; 
407           break;
408         default:
409         continue;
410         }
411         
412         aComment.sprintf("myComment=ENTITY;myType=%d;myMeshName=%s;myId=%d",
413                          VISU::TENTITY,
414                          aMeshName.c_str(),
415                          anEntity);
416         
417         aMeshOnEntity->myEntry = 
418           CreateAttributes(theStudy, 
419                            aSubMeshesEntry, 
420                            "", 
421                            anEntityName.c_str(), 
422                            "", 
423                            aComment.latin1(), 
424                            true);
425       }
426     }
427     
428     ProcessVoidEvent(new TUpdateObjBrowser(theStudy->StudyId(),theIsDone));
429   }
430
431   //---------------------------------------------------------------
432   void
433   BuildGroups(Result_i* theResult,
434               VISU_Convertor* theInput,
435               CORBA::Boolean* theIsDone,
436               CORBA::Boolean theIsBuild,
437               _PTR(Study) theStudy)
438   {
439     if(!theIsBuild || *theIsDone)
440       return;
441
442     TTimerLog aTimerLog(MYTIMEDEBUG,"Result_i::BuildGroups");
443     TResultManager aResultManager(theResult);
444     TTransactionManager aTransactionManager(theStudy);
445     
446     {
447       TTimerLog aTimerLog(MYTIMEDEBUG,"theInput->BuildGroups");
448       theInput->BuildGroups();
449     }
450
451     QString aComment;
452     const TMeshMap& aMeshMap = theInput->GetMeshMap();
453     TMeshMap::const_iterator aMeshMapIter = aMeshMap.begin();
454     for(; aMeshMapIter != aMeshMap.end(); aMeshMapIter++){
455       const string& aMeshName = aMeshMapIter->first;
456       const PMesh& aMesh = aMeshMapIter->second;
457       
458       const TMeshOnEntityMap& aMeshOnEntityMap = aMesh->myMeshOnEntityMap;
459       if(aMeshOnEntityMap.empty()) 
460         continue;
461       
462       TMeshOnEntityMap::const_iterator aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
463       for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++){
464         const TEntity& anEntity = aMeshOnEntityMapIter->first;
465         const PMeshOnEntity& aMeshOnEntity = aMeshOnEntityMapIter->second;
466         
467         const TFamilyMap& aFamilyMap = aMeshOnEntity->myFamilyMap;
468         TFamilyMap::const_iterator aFamilyMapIter = aFamilyMap.begin();
469         for(; aFamilyMapIter != aFamilyMap.end(); aFamilyMapIter++){
470           const string& aFamilyName = aFamilyMapIter->first;
471           const PFamily& aFamily = aFamilyMapIter->second;
472           aComment.sprintf("myComment=FAMILY;myType=%d;myMeshName=%s;myEntityId=%d;myName=%s",
473                            TFAMILY,
474                            aMeshName.c_str(),
475                            anEntity,
476                            aFamilyName.c_str());
477           aFamily->myEntry =
478             CreateAttributes(theStudy,
479                              aMeshOnEntity->myEntry,
480                              "",
481                              aFamilyName,
482                              "",
483                              aComment.latin1(),
484                              true);
485         }
486       }
487       //Importing groups
488       const TGroupMap& aGroupMap = aMesh->myGroupMap;
489       if(!aGroupMap.empty()){
490         aComment.sprintf("myComment=GROUPS;myMeshName=%s",
491                          aMeshName.c_str());
492         string aGroupsEntry =
493           CreateAttributes(theStudy,
494                            aMesh->myEntry,
495                            "",
496                            "Groups",
497                            "",
498                            aComment.latin1(),
499                            true);
500         TGroupMap::const_iterator aGroupMapIter = aGroupMap.begin();
501         for(; aGroupMapIter != aGroupMap.end(); aGroupMapIter++){
502           const string& aGroupName = aGroupMapIter->first;
503           const PGroup& aGroup = aGroupMapIter->second;
504           aComment.sprintf("myComment=GROUP;myType=%d;myMeshName=%s;myName=%s",
505                            TGROUP,aMeshName.c_str(),aGroupName.c_str());
506           aGroup->myEntry = 
507             CreateAttributes(theStudy,
508                              aGroupsEntry,
509                              "",
510                              aGroupName,
511                              "",
512                              aComment.latin1(),
513                              true);
514           const TFamilySet& aFamilySet = aGroup->myFamilySet;
515           TFamilySet::const_iterator aFamilyIter = aFamilySet.begin();
516           for(; aFamilyIter != aFamilySet.end(); aFamilyIter++){
517             const PFamily& aFamily = *aFamilyIter;
518             CreateReference(theStudy,
519                             aGroup->myEntry,
520                             aFamily->myEntry);
521           }
522         }
523       }
524     }
525     
526     ProcessVoidEvent(new TUpdateObjBrowser(theStudy->StudyId(),theIsDone));
527   }
528
529
530   //---------------------------------------------------------------
531   void
532   BuildFields(Result_i* theResult,
533               VISU_Convertor* theInput,
534               CORBA::Boolean* theIsDone,
535               CORBA::Boolean theIsBuild,
536               _PTR(Study) theStudy)
537   {
538     if(!theIsBuild || *theIsDone)
539       return;
540
541     TTimerLog aTimerLog(MYTIMEDEBUG,"Result_i::BuildFields");
542     TResultManager aResultManager(theResult);
543     TTransactionManager aTransactionManager(theStudy);
544
545     {
546       TTimerLog aTimerLog(MYTIMEDEBUG,"theInput->BuildFields");
547       theInput->BuildFields();
548     }
549
550     QString aComment;
551     const TMeshMap& aMeshMap = theInput->GetMeshMap();
552     TMeshMap::const_iterator aMeshMapIter = aMeshMap.begin();
553     for(; aMeshMapIter != aMeshMap.end(); aMeshMapIter++){
554       const string& aMeshName = aMeshMapIter->first;
555       const PMesh& aMesh = aMeshMapIter->second;
556       
557       const TMeshOnEntityMap& aMeshOnEntityMap = aMesh->myMeshOnEntityMap;
558       if(aMeshOnEntityMap.empty()) 
559         continue;
560       
561       //Import fields
562       string aFieldsEntry;
563       bool anIsFieldsEntryCreated = false;
564       
565       TMeshOnEntityMap::const_iterator aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
566       for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++){
567         const TEntity& anEntity = aMeshOnEntityMapIter->first;
568         const PMeshOnEntity& aMeshOnEntity = aMeshOnEntityMapIter->second;
569         const TFieldMap& aFieldMap = aMeshOnEntity->myFieldMap;
570         TFieldMap::const_iterator aFieldMapIter = aFieldMap.begin();
571         for(; aFieldMapIter != aFieldMap.end(); aFieldMapIter++){
572           if(!anIsFieldsEntryCreated){
573             aComment.sprintf("myComment=FIELDS;myMeshName=%s",
574                              aMeshName.c_str());
575             aFieldsEntry =
576               CreateAttributes(theStudy,
577                                aMesh->myEntry,
578                                "",
579                                "Fields",
580                                "",
581                                aComment.latin1(),
582                                true);
583             anIsFieldsEntryCreated = true;
584           }
585           const string& aFieldName = aFieldMapIter->first;
586           const PField& aField = aFieldMapIter->second;
587           const TValField& aValField = aField->myValField;
588           QString aFieldNameWithUnit = GenerateFieldName(aFieldName,aField->myUnitNames[0]);
589           aComment.sprintf("myComment=FIELD;myType=%d;myMeshName=%s;myEntityId=%d;myName=%s;myNbTimeStamps=%d;myNumComponent=%d",
590                            TFIELD,
591                            aMeshName.c_str(),
592                            anEntity,
593                            aFieldName.c_str(),
594                            aValField.size(),
595                            aField->myNbComp);
596           aField->myEntry = 
597             CreateAttributes(theStudy,
598                              aFieldsEntry,
599                              "",
600                              aFieldNameWithUnit.latin1(),
601                              "",
602                              aComment.latin1(),
603                              true);
604           CreateReference(theStudy,
605                           aField->myEntry,
606                           aMeshOnEntity->myEntry);
607           TValField::const_iterator aValFieldIter = aValField.begin();
608           for(; aValFieldIter != aValField.end(); aValFieldIter++){
609             int aTimeStamp = aValFieldIter->first;
610             const PValForTime& aValForTime = aValFieldIter->second;
611             aComment.sprintf("myComment=TIMESTAMP;myType=%d;myMeshName=%s;myEntityId=%d;myFieldName=%s;myTimeStampId=%d;myNumComponent=%d",
612                              TTIMESTAMP,
613                              aMeshName.c_str(),
614                              anEntity,
615                              aFieldName.c_str(),
616                              aTimeStamp,
617                              aField->myNbComp);
618             string aTimeStampId = VISU_Convertor::GenerateName(aValForTime->myTime);
619             aValForTime->myEntry = 
620               CreateAttributes(theStudy,
621                                aField->myEntry,
622                                "",
623                                aTimeStampId,
624                                "",
625                                aComment.latin1(),
626                                true);
627           }
628         }
629       }
630     }
631     
632     ProcessVoidEvent(new TUpdateObjBrowser(theStudy->StudyId(),theIsDone));
633   }
634
635
636   //---------------------------------------------------------------
637   void
638   BuildMinMax(Result_i* theResult,
639               VISU_Convertor* theInput,
640               CORBA::Boolean* theIsDone,
641               CORBA::Boolean theIsBuild,
642               Result_i::TUpdateMinMaxSignal* theUpdateMinMaxSignal)
643   {
644     if(!theIsBuild || *theIsDone)
645       return;
646
647     TTimerLog aTimerLog(MYTIMEDEBUG,"Result_i::BuildMinMax");
648     TResultManager aResultManager(theResult);
649     
650     theInput->BuildMinMax();
651
652     *theIsDone = true;
653
654     (*theUpdateMinMaxSignal)();
655   }
656
657
658   //---------------------------------------------------------------
659   void
660   BuildFieldDataTree(Result_i* theResult,
661                      VISU_Convertor* theInput,
662                      CORBA::Boolean* theIsFieldsDone,
663                      CORBA::Boolean theIsBuildFields,
664                      CORBA::Boolean* theIsMinMaxDone,
665                      CORBA::Boolean theIsBuildMinMax,
666                      Result_i::TUpdateMinMaxSignal* theUpdateMinMaxSignal,
667                      _PTR(Study) theStudy)
668   {
669     BuildFields(theResult,
670                 theInput,
671                 theIsFieldsDone,
672                 theIsBuildFields,
673                 theStudy);
674
675     BuildMinMax(theResult,
676                 theInput,
677                 theIsMinMaxDone,
678                 theIsBuildMinMax,
679                 theUpdateMinMaxSignal);
680   }
681   
682
683   //---------------------------------------------------------------
684   struct TBuildArgs
685   {
686     Result_i* myResult;
687     VISU_Convertor* myInput;
688     CORBA::Boolean* myIsEntitiesDone;
689     std::string myResultEntry;
690     CORBA::Boolean* myIsFieldsDone;
691     CORBA::Boolean myIsBuildFields;
692     CORBA::Boolean* myIsMinMaxDone;
693     CORBA::Boolean myIsBuildMinMax;
694     Result_i::TUpdateMinMaxSignal* myUpdateMinMaxSignal;
695     CORBA::Boolean* myIsGroupsDone;
696     CORBA::Boolean myIsBuildGroups;
697     _PTR(Study) myStudy;
698
699     TBuildArgs(Result_i* theResult,
700                VISU_Convertor* theInput,
701                CORBA::Boolean* theIsEntitiesDone,
702                std::string theResultEntry,
703                CORBA::Boolean* theIsFieldsDone,
704                CORBA::Boolean theIsBuildFields,
705                CORBA::Boolean* theIsMinMaxDone,
706                CORBA::Boolean theIsBuildMinMax,
707                Result_i::TUpdateMinMaxSignal* theUpdateMinMaxSignal,
708                CORBA::Boolean* theIsGroupsDone,
709                CORBA::Boolean theIsBuildGroups,
710                _PTR(Study) theStudy):
711       myResult(theResult),
712       myInput(theInput),
713       myIsEntitiesDone(theIsEntitiesDone),
714       myResultEntry(theResultEntry),
715       myIsFieldsDone(theIsFieldsDone),
716       myIsBuildFields(theIsBuildFields),
717       myIsMinMaxDone(theIsMinMaxDone),
718       myIsBuildMinMax(theIsBuildMinMax),
719       myUpdateMinMaxSignal(theUpdateMinMaxSignal),
720       myIsGroupsDone(theIsGroupsDone),
721       myIsBuildGroups(theIsBuildGroups),
722       myStudy(theStudy)
723     {}
724       
725   };
726
727   //---------------------------------------------------------------
728   void
729   BuildDataTree(TBuildArgs theBuildArgs)
730   {
731     BuildEntities(theBuildArgs.myResult,
732                   theBuildArgs.myInput,
733                   theBuildArgs.myIsEntitiesDone,
734                   theBuildArgs.myResultEntry,
735                   theBuildArgs.myStudy);
736     {
737       boost::thread aThread(boost::bind(&BuildGroups,
738                                         theBuildArgs.myResult,
739                                         theBuildArgs.myInput,
740                                         theBuildArgs.myIsGroupsDone,
741                                         theBuildArgs.myIsBuildGroups,
742                                         theBuildArgs.myStudy));
743     }
744     {
745       boost::thread aThread(boost::bind(&BuildFieldDataTree,
746                                         theBuildArgs.myResult,
747                                         theBuildArgs.myInput,
748                                         theBuildArgs.myIsFieldsDone,
749                                         theBuildArgs.myIsBuildFields,
750                                         theBuildArgs.myIsMinMaxDone,
751                                         theBuildArgs.myIsBuildMinMax,
752                                         theBuildArgs.myUpdateMinMaxSignal,
753                                         theBuildArgs.myStudy));
754     }
755   }
756   
757 }
758
759
760 //---------------------------------------------------------------
761 VISU::MinMaxCunsomer
762 ::MinMaxCunsomer():
763   myMinMaxIsInitilized(false)
764 {}
765
766 bool
767 VISU::MinMaxCunsomer
768 ::IsMinMaxInitilized()
769 {
770   return myMinMaxIsInitilized;
771 }
772
773 void
774 VISU::MinMaxCunsomer
775 ::UpdateMinMax()
776 {
777   myMinMaxIsInitilized = true;
778 }
779
780
781 //---------------------------------------------------------------
782 const string VISU::Result_i::myComment = "RESULT";
783 const char* VISU::Result_i::GetComment() const { return myComment.c_str();}
784
785 //---------------------------------------------------------------
786 VISU::Result_i
787 ::Result_i (SALOMEDS::Study_ptr theStudy,
788             const ESourceId& theSourceId,
789             const ECreationId& theCreationId,
790             CORBA::Boolean theIsBuildImmediately):
791   myStudyDocument(SALOMEDS::Study::_duplicate(theStudy)),
792   myCreationId(theCreationId),
793   mySourceId(theSourceId),
794   myIsBuildImmediately(theIsBuildImmediately),
795   myInput(NULL),
796   myIsEntitiesDone(false),
797   myIsFieldsDone(false),
798   myIsGroupsDone(false),
799   myIsMinMaxDone(false),
800   myIsBuildFields(true),
801   myIsBuildGroups(true),
802   myIsBuildMinMax(true),
803   myIsAllDone(false)
804 {
805   myStudy = ProcessEvent(new TGetStudy(myStudyDocument->StudyId()));
806 }
807
808
809 //---------------------------------------------------------------
810 void
811 VISU::Result_i
812 ::RemoveFromStudy()
813 {
814   struct TRemoveFromStudy: public SALOME_Event
815   {
816     VISU::Result_i* myRemovable;
817     TRemoveFromStudy(VISU::Result_i* theRemovable):
818       myRemovable(theRemovable)
819     {}
820     
821     virtual
822     void
823     Execute()
824     {
825       VISU::RemoveFromStudy(myRemovable->GetSObject(),false);
826       myRemovable->Destroy();
827     }
828   };
829
830   // Remove the result with all presentations and other possible sub-objects
831   ProcessVoidEvent(new TRemoveFromStudy(this));
832 }
833
834
835 //---------------------------------------------------------------
836 void 
837 VISU::Result_i
838 ::MinMaxConnect(VISU::MinMaxCunsomer* theMinMaxCunsomer)
839 {
840   myUpdateMinMaxSignal.connect(boost::bind(&MinMaxCunsomer::UpdateMinMax,theMinMaxCunsomer));
841 }
842
843
844 //---------------------------------------------------------------
845 int
846 VISU::Result_i
847 ::IsPossible()
848 {
849   try{
850     float aSize = myInput->GetSize();
851     bool aResult = VISU_PipeLine::CheckAvailableMemory(aSize);
852     MESSAGE("Result_i::IsPossible - CheckAvailableMemory = "<<float(aSize)<<"; aResult = "<<float(aResult));
853     return aResult;
854   }catch(std::exception& exc){
855     INFOS("Follow exception was occured :\n"<<exc.what());
856   }catch(...){
857     INFOS("Unknown exception was occured!");
858   }
859   return 0;
860 }
861
862
863 //---------------------------------------------------------------
864 CORBA::Boolean
865 VISU::Result_i
866 ::BuildAll()
867 {
868   if(MYDEBUG) MESSAGE("Result_i::Build - myIsAllDone = "<<myIsAllDone);
869   if(myIsAllDone) 
870     return 1;
871   if(!IsPossible()) 
872     return 0;
873   try{
874     const VISU::TMeshMap& aMeshMap = myInput->GetMeshMap();
875     VISU::TMeshMap::const_iterator aMeshMapIter = aMeshMap.begin();
876     for(; aMeshMapIter != aMeshMap.end(); aMeshMapIter++){
877       const string& aMeshName = aMeshMapIter->first;
878       const VISU::PMesh aMesh = aMeshMapIter->second;
879       const VISU::TMeshOnEntityMap& aMeshOnEntityMap = aMesh->myMeshOnEntityMap;
880       VISU::TMeshOnEntityMap::const_iterator aMeshOnEntityMapIter;
881       //Import fields
882       aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
883       for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++){
884         const VISU::TEntity& anEntity = aMeshOnEntityMapIter->first;
885         const VISU::PMeshOnEntity aMeshOnEntity = aMeshOnEntityMapIter->second;
886         const VISU::TFieldMap& aFieldMap = aMeshOnEntity->myFieldMap;
887         VISU::TFieldMap::const_iterator aFieldMapIter = aFieldMap.begin();
888         for(; aFieldMapIter != aFieldMap.end(); aFieldMapIter++){
889           const string& aFieldName = aFieldMapIter->first;
890           const VISU::PField aField = aFieldMapIter->second;
891           const VISU::TValField& aValField = aField->myValField;
892           VISU::TValField::const_iterator aValFieldIter = aValField.begin();
893           for(; aValFieldIter != aValField.end(); aValFieldIter++){
894             int aTimeStamp = aValFieldIter->first;
895             try{
896               myInput->GetTimeStampOnMesh(aMeshName,anEntity,aFieldName,aTimeStamp);
897             }catch(std::exception& exc){
898               INFOS("Follow exception was occured :\n"<<exc.what());
899             }catch(...){
900               INFOS("Unknown exception was occured!!!");
901             }
902           }
903         }
904         //Importing groups
905         const VISU::TGroupMap& aGroupMap = aMesh->myGroupMap;
906         VISU::TGroupMap::const_iterator aGroupMapIter = aGroupMap.begin();
907         for(; aGroupMapIter != aGroupMap.end(); aGroupMapIter++){
908           const string& aGroupName = aGroupMapIter->first;
909           try{
910             myInput->GetMeshOnGroup(aMeshName,aGroupName);
911           }catch(std::exception& exc){
912             INFOS("Follow exception was occured :\n"<<exc.what());
913           }catch(...){
914             INFOS("Unknown exception was occured!!!");
915           }
916         }
917         //Import families
918         const VISU::TFamilyMap& aFamilyMap = aMeshOnEntity->myFamilyMap;
919         VISU::TFamilyMap::const_iterator aFamilyMapIter = aFamilyMap.begin();
920         for(; aFamilyMapIter != aFamilyMap.end(); aFamilyMapIter++){
921           const string& aFamilyName = aFamilyMapIter->first;
922           try{
923             myInput->GetFamilyOnEntity(aMeshName,anEntity,aFamilyName);
924           }catch(std::exception& exc){
925             INFOS("Follow exception was occured :\n"<<exc.what());
926           }catch(...){
927             INFOS("Unknown exception was occured!!!");
928           }
929         }
930         //Import mesh on entity
931         try{
932           myInput->GetMeshOnEntity(aMeshName,anEntity);
933         }catch(std::exception& exc){
934           INFOS("Follow exception was occured :\n"<<exc.what());
935         }catch(...){
936           INFOS("Unknown exception was occured!!!");
937         }
938       }
939     }
940     myIsAllDone = 1;
941   }catch(std::exception& exc){
942     INFOS("Follow exception was occured :\n"<<exc.what());
943   }catch(...){
944     INFOS("Unknown exception was occured!!!");
945   }
946   return myIsAllDone;
947 }
948
949
950 //---------------------------------------------------------------
951 CORBA::Boolean
952 VISU::Result_i
953 ::Build(CORBA::Boolean theIsBuildAll,
954         CORBA::Boolean theIsAtOnce)
955 {
956   if(theIsBuildAll)
957     theIsAtOnce = true;
958
959   if(Build(SALOMEDS::SObject::_nil(),theIsAtOnce)){
960     if(theIsBuildAll)
961       return BuildAll();
962     return true;
963   }
964
965   return false;
966 }
967
968
969 //---------------------------------------------------------------
970 VISU::Storable*
971 VISU::Result_i
972 ::Build(SALOMEDS::SObject_ptr theSObject,
973         CORBA::Boolean theIsAtOnce)
974 {
975   if(!myInput)
976     return NULL;
977
978   if(IsDone())
979     return this;
980
981   mySComponent = FindOrCreateVisuComponent(myStudyDocument);
982   CORBA::String_var aSComponentEntry = mySComponent->GetID();
983   CORBA::String_var anIOR(GetID());
984   QString aComment;
985   aComment.sprintf("myComment=%s;myType=%d;myFileName=%s;myInitFileName=%s",
986                    GetComment(),
987                    VISU::TRESULT,
988                    myFileInfo.filePath().latin1(),
989                    myInitFileName.c_str()); // Restoring of Python dump
990   string aResultEntry =
991     CreateAttributes(myStudy,
992                      aSComponentEntry.in(),
993                      anIOR.in(),
994                      myName,
995                      "",
996                      aComment.latin1(),
997                      true);
998   mySObject = myStudyDocument->FindObjectID(aResultEntry.c_str());
999   if(!CORBA::is_nil(theSObject)){
1000     CORBA::String_var aString = theSObject->GetID();
1001     CreateReference(myStudyDocument,aResultEntry,aString.in());
1002   }
1003
1004   if(theIsAtOnce){
1005     BuildEntities(this,
1006                   myInput,
1007                   &myIsEntitiesDone,
1008                   aResultEntry,
1009                   myStudy);
1010     
1011     BuildGroups(this,
1012                 myInput,
1013                 &myIsGroupsDone,
1014                 myIsBuildGroups,
1015                 myStudy);
1016
1017     BuildFields(this,
1018                 myInput,
1019                 &myIsFieldsDone,
1020                 myIsBuildFields,
1021                 myStudy);
1022     
1023     BuildMinMax(this,
1024                 myInput,
1025                 &myIsMinMaxDone,
1026                 myIsBuildMinMax,
1027                 &myUpdateMinMaxSignal);
1028     
1029   }else{
1030     TBuildArgs aBuildArgs(this,
1031                           myInput,
1032                           &myIsEntitiesDone,
1033                           aResultEntry,
1034                           &myIsFieldsDone,
1035                           myIsBuildFields,
1036                           &myIsMinMaxDone,
1037                           myIsBuildMinMax,
1038                           &myUpdateMinMaxSignal,
1039                           &myIsGroupsDone,
1040                           myIsBuildGroups,
1041                           myStudy);
1042     boost::thread aThread(boost::bind(&BuildDataTree,
1043                                       aBuildArgs));
1044   }
1045
1046   return this;
1047 }
1048
1049
1050 //---------------------------------------------------------------
1051 VISU::Storable*
1052 VISU::Result_i
1053 ::BuildAll(SALOMEDS::SObject_ptr theSObject)
1054 {
1055   if(MYDEBUG) MESSAGE("Result_i::Build");
1056   try{
1057     Build(theSObject);
1058     BuildAll();
1059   }catch(std::exception& exc){
1060     INFOS("Follow exception was occured :\n"<<exc.what());
1061     return NULL;
1062   }catch(...){
1063     INFOS("Unknown exception was occured!!!");
1064     return NULL;
1065   }
1066
1067   return this;
1068 }
1069
1070
1071 //---------------------------------------------------------------
1072 VISU::Storable*
1073 VISU::Result_i::
1074 Create(const char* theFileName)
1075 {
1076   try{
1077     myFileInfo.setFile(theFileName);
1078     myInitFileName = myFileInfo.filePath().latin1();
1079     myName = ::GenerateName(myFileInfo.fileName()).latin1();
1080     if(mySourceId == eRestoredFile){
1081       std::string aTmpDir(SALOMEDS_Tool::GetTmpDir());
1082       static QString aCommand;
1083       aCommand.sprintf("cp %s %s",myFileInfo.absFilePath().latin1(),aTmpDir.c_str());
1084       if(system(aCommand) == -1){
1085         MESSAGE("Create - Can't execute the command :"<<aCommand);
1086         return NULL;
1087       }
1088       if(MYDEBUG) MESSAGE("Result_i::Create - aCommand = "<<aCommand);
1089       myFileInfo.setFile(QString(aTmpDir.c_str()) + myFileInfo.fileName());
1090     }
1091     myInput = CreateConvertor(myFileInfo.absFilePath().latin1());
1092     if(myInput){
1093       if(myIsBuildImmediately)
1094         Build(SALOMEDS::SObject::_nil());
1095       return this;
1096     }
1097   }catch(std::exception& exc){
1098     INFOS("Follow exception was occured :\n"<<exc.what());
1099   }catch(...){
1100     INFOS("Unknown exception was occured!!!");
1101   }
1102   return NULL;
1103 }
1104
1105
1106 //---------------------------------------------------------------
1107 VISU::Storable*
1108 VISU::Result_i::
1109 Create(SALOMEDS::SObject_ptr theMedSObject)
1110 {
1111   if(MYDEBUG)  MESSAGE("Result_i::Create MedObject from SALOMEDS::SObject_ptr");
1112   try{
1113     myInput = CreateMEDConvertor(theMedSObject);
1114     if(myInput == NULL)
1115       return NULL;
1116
1117     myInput->Build();
1118
1119     string aCompDataType = GetComponentDataType(theMedSObject);
1120     myFileInfo.setFile(aCompDataType.c_str());
1121     myInitFileName = aCompDataType;
1122
1123     myName = ::GenerateName("aResult").latin1();
1124
1125     return Build(theMedSObject);
1126   }catch(std::exception& exc){
1127     INFOS("Follow exception was occured :\n"<<exc.what());
1128   }catch(...){
1129     INFOS("Unknown exception was occured!!!");
1130   }
1131   return NULL;
1132 }
1133
1134
1135 //---------------------------------------------------------------
1136 VISU::Storable*
1137 VISU::Result_i::
1138 Create(SALOME_MED::FIELD_ptr theField)
1139 {
1140   if(MYDEBUG)  MESSAGE("Result_i::Create MedObject from SALOME_MED::FIELD_ptr");
1141   try{
1142     myInput = CreateMEDFieldConvertor(theField);
1143     if(myInput == NULL)
1144       return NULL;
1145
1146     myInput->Build();
1147
1148     string aCompDataType = "MED";
1149     myFileInfo.setFile(aCompDataType.c_str());
1150     myInitFileName = aCompDataType;
1151
1152     myName = ::GenerateName("aResult").latin1();
1153
1154     CORBA::String_var anIOR = myStudyDocument->ConvertObjectToIOR(theField);
1155     SALOMEDS::SObject_var aFieldSObject = myStudyDocument->FindObjectIOR(anIOR);
1156
1157     return Build(aFieldSObject);
1158   }catch(std::exception& exc){
1159     INFOS("Follow exception was occured :\n"<<exc.what());
1160   }catch(...){
1161     INFOS("Unknown exception was occured!!!");
1162   }
1163   return NULL;
1164 }
1165
1166
1167 //---------------------------------------------------------------
1168 VISU::Storable*
1169 VISU::Result_i::
1170 Restore(SALOMEDS::SObject_ptr theSObject,
1171         const Storable::TRestoringMap& theMap,
1172         const string& thePrefix)
1173 {
1174   if(MYDEBUG) MESSAGE("Result_i::Restore - " << thePrefix);
1175   try {
1176     mySObject = SALOMEDS::SObject::_duplicate(theSObject);
1177     myStudyDocument = mySObject->GetStudy();
1178     mySComponent = mySObject->GetFatherComponent();
1179     myName = VISU::Storable::FindValue(theMap, "myName").latin1();
1180     myInitFileName = VISU::Storable::FindValue(theMap, "myInitFileName").latin1();
1181
1182     SALOMEDS::SObject_var aRefSObj, aTargetRefSObj;
1183     if (mySObject->FindSubObject(1, aRefSObj) &&
1184         aRefSObj->ReferencedObject(aTargetRefSObj)) {
1185       if(MYDEBUG) MESSAGE("Result_i::GetInput - There is some reference.");
1186       SALOMEDS::SComponent_var aCompRefSObj = aTargetRefSObj->GetFatherComponent();
1187       CORBA::String_var aDataType = aCompRefSObj->ComponentDataType();
1188       myFileInfo.setFile(aDataType.in());
1189       if(MYDEBUG) MESSAGE("Result_i::GetInput - aDataType = " << aDataType);
1190       Engines::Component_var aEngComp =
1191         Base_i::myEnginesLifeCycle->FindOrLoad_Component("FactoryServer", aDataType.in());
1192       if (CORBA::is_nil(aEngComp))
1193         throw std::runtime_error("Restore - There is no aEngComp for the aDataType !!!");
1194       SALOMEDS::StudyBuilder_var aStudyBuilder = myStudyDocument->NewBuilder();
1195       SALOMEDS::Driver_var aDriver = SALOMEDS::Driver::_narrow(aEngComp);
1196       aStudyBuilder->LoadWith(aCompRefSObj, aDriver);
1197       if (strcmp(aDataType, "MED") == 0){
1198         // create field or MED converter
1199         CORBA::Object_var aMedObject = VISU::SObjectToObject(aTargetRefSObj);
1200         SALOME_MED::FIELD_var aField = SALOME_MED::FIELD::_narrow(aMedObject);
1201         if(!CORBA::is_nil(aField))
1202           myInput = CreateMEDFieldConvertor(aField);
1203         else
1204           myInput = CreateMEDConvertor(aTargetRefSObj);
1205         myInput->Build();
1206       }else
1207         throw std::runtime_error("GetInput - There is no convertor for the aDataType !!!");
1208     } else {
1209       myFileInfo.setFile(thePrefix.c_str());
1210
1211       string aStudyPrefix ("");
1212       if (IsMultifile())
1213         aStudyPrefix = SALOMEDS_Tool::GetNameFromPath(myStudyDocument->URL());
1214       if (!myFileInfo.isFile()) {
1215         string aFileName = thePrefix + aStudyPrefix + "_" + myName;
1216         myFileInfo.setFile(aFileName.c_str());
1217       }
1218       if(MYDEBUG)
1219         MESSAGE("Result_i::Restore - aFileName = " << myFileInfo.filePath() << "; " << myFileInfo.isFile());
1220
1221       const char* aPathLatin = myFileInfo.filePath().latin1();
1222       if (HDFascii::isASCII(aPathLatin)) {
1223         MESSAGE("ConvertFromASCIIToHDF(" << aPathLatin << ")");
1224         char* aResultPath = HDFascii::ConvertFromASCIIToHDF(aPathLatin);
1225         MESSAGE("ConvertFromASCIIToHDF() DONE : " << aResultPath);
1226         char* aHDFFileName = new char[strlen(aResultPath) + 19];
1227         sprintf(aHDFFileName, "%shdf_from_ascii.hdf", aResultPath);
1228
1229         if (IsMultifile()) { // set this file as new - temporary
1230           static QString aCommand;
1231           aCommand.sprintf("mv %s %s%s",aHDFFileName, aResultPath, myFileInfo.baseName().latin1());
1232           if (system(aCommand) == -1) {
1233             if(MYDEBUG) MESSAGE("VISU::Result_i::Restore - Can't execute the command :" << aCommand);
1234             return NULL;
1235           } else {
1236             if(MYDEBUG) MESSAGE("VISU::Result_i::Restore - " << aCommand);
1237           }
1238           myFileInfo.setFile(QString(aResultPath) + QString(myFileInfo.baseName().latin1()));
1239         } else { // change current temporary file to the new: with hdf-format
1240           static QString aCommand;
1241           aCommand.sprintf("mv %s %s\0",aHDFFileName, myFileInfo.filePath().latin1());
1242           if (system(aCommand.latin1()) == -1) {
1243             if(MYDEBUG) MESSAGE("VISU::Result_i::Restore - Can't execute the command :" << aCommand);
1244             return NULL;
1245           } else {
1246             if(MYDEBUG) MESSAGE("VISU::Result_i::Restore - " << aCommand);
1247           }
1248           SALOMEDS::ListOfFileNames_var anEmptyList = new SALOMEDS::ListOfFileNames;
1249           SALOMEDS_Tool::RemoveTemporaryFiles(aResultPath, anEmptyList.in(), true);
1250         }
1251         mySourceId = eRestoredFile;
1252         delete(aResultPath);
1253         delete(aHDFFileName);
1254       } else if (!IsMultifile()) {
1255         mySourceId = eRestoredFile;
1256       } else {
1257         mySourceId = eFile;
1258       }
1259       if(MYDEBUG) MESSAGE("VISU::Result_i::Restore - mySourceId = " << mySourceId);
1260       myInput = CreateConvertor(myFileInfo.filePath().latin1());
1261       myInput->Build();
1262       QString aComment;
1263       aComment.sprintf("myComment=%s;myType=%d;myFileName=%s;myInitFileName=%s",
1264                        GetComment(), VISU::TRESULT, myFileInfo.filePath().latin1(),
1265                        myInitFileName.c_str()); // Restoring of Python dump
1266       SALOMEDS::GenericAttribute_var anAttr;
1267       if (!theSObject->FindAttribute(anAttr, "AttributeComment"))
1268         throw std::runtime_error("Build - There is no AttributeComment for the SObject !!!");
1269       SALOMEDS::AttributeComment_var aCmnt = SALOMEDS::AttributeComment::_narrow(anAttr);
1270       aCmnt->SetValue(aComment.latin1());
1271     }
1272     bool isBuildAll = VISU::GetResourceMgr()->booleanValue("VISU", "full_med_loading", false);
1273     if (isBuildAll)
1274       BuildAll();
1275     return this;
1276   } catch(std::exception& exc) {
1277     INFOS("Follow exception was occured :\n"<<exc.what());
1278   } catch(...) {
1279     INFOS("Unknown exception was occured!!!");
1280   }
1281   return NULL;
1282 }
1283
1284 //---------------------------------------------------------------
1285 VISU::Result_i::TInput* 
1286 VISU::Result_i
1287 ::GetInput() 
1288 {
1289   return myInput;
1290 }
1291
1292 //---------------------------------------------------------------
1293 CORBA::Boolean 
1294 VISU::Result_i
1295 ::IsDone() 
1296 {
1297   return 
1298     myIsEntitiesDone && 
1299     (myIsBuildFields? myIsFieldsDone: true) &&
1300     (myIsBuildMinMax? myIsMinMaxDone: true) &&
1301     (myIsBuildGroups? myIsGroupsDone: true);
1302 }
1303
1304 CORBA::Boolean 
1305 VISU::Result_i
1306 ::IsEntitiesDone() 
1307 {
1308   return myIsEntitiesDone;
1309 }
1310
1311 void
1312 VISU::Result_i
1313 ::SetBuildFields(CORBA::Boolean theIsBuildFields, 
1314                  CORBA::Boolean theIsCalculateMinMax)
1315 {
1316   myIsBuildFields = theIsBuildFields;
1317   if(theIsBuildFields)
1318     myIsBuildMinMax = theIsCalculateMinMax;
1319   else
1320     myIsBuildMinMax = false;
1321 }
1322
1323 void
1324 VISU::Result_i
1325 ::SetBuildGroups(CORBA::Boolean theIsBuildGroups)
1326 {
1327   myIsBuildGroups = theIsBuildGroups;
1328 }
1329
1330 CORBA::Boolean 
1331 VISU::Result_i
1332 ::IsFieldsDone() 
1333 {
1334   return myIsFieldsDone;
1335 }
1336
1337 CORBA::Boolean 
1338 VISU::Result_i
1339 ::IsGroupsDone() 
1340 {
1341   return myIsGroupsDone;
1342 }
1343
1344 CORBA::Boolean 
1345 VISU::Result_i
1346 ::IsMinMaxDone() 
1347 {
1348   return myIsMinMaxDone;
1349 }
1350
1351 //---------------------------------------------------------------
1352 void 
1353 VISU::Result_i
1354 ::ToStream(std::ostringstream& theStr)
1355 {
1356   if(MYDEBUG) MESSAGE(GetComment());
1357   Storable::DataToStream(theStr,"myName",myName.c_str());
1358   Storable::DataToStream(theStr,"myInitFileName",myInitFileName.c_str());
1359   Storable::DataToStream(theStr,"myCreationId",myCreationId);
1360 }
1361
1362
1363 //---------------------------------------------------------------
1364 VISU::Storable*
1365 VISU::Result_i
1366 ::Restore(SALOMEDS::SObject_ptr theSObject,
1367           const string& thePrefix,
1368           const Storable::TRestoringMap& theMap)
1369 {
1370   SALOMEDS::Study_var aStudy = theSObject->GetStudy();
1371
1372   ECreationId aCreationId = ECreationId(Storable::FindValue(theMap,"myCreationId").toInt());
1373   ESourceId aSourceId = eRestoredFile;
1374   if(aCreationId == eImportMed || aCreationId == eImportMedField)
1375     aSourceId = eRestoredComponent;
1376
1377   VISU::Result_i* pResult = new VISU::Result_i(aStudy,aSourceId,aCreationId);
1378   if (pResult == NULL)
1379     return NULL;
1380
1381   return pResult->Restore(theSObject,theMap,thePrefix);
1382 }
1383
1384
1385 //---------------------------------------------------------------
1386 string 
1387 VISU::Result_i
1388 ::GetRefFatherEntry() 
1389 {
1390   return "";
1391 }
1392
1393 string
1394 VISU::Result_i
1395 ::GetEntry()
1396 {
1397   CORBA::String_var anEntry = mySObject->GetID();
1398   return string(anEntry);
1399 }
1400
1401 const SALOMEDS::SObject_var& 
1402 VISU::Result_i
1403 ::GetSObject() const 
1404
1405   return mySObject;
1406 }
1407
1408 const SALOMEDS::Study_var& 
1409 VISU::Result_i
1410 ::GetStudyDocument() const 
1411
1412   return myStudyDocument;
1413 }
1414
1415 const SALOMEDS::SComponent_var& 
1416 VISU::Result_i
1417 ::GetSComponent() const
1418 {
1419   return mySComponent;
1420 }
1421
1422 std::string 
1423 VISU::Result_i
1424 ::GetEntry(const std::string& theComment)
1425 {
1426   return FindEntryWithComment(myStudyDocument,GetEntry().c_str(),theComment.c_str());
1427 }
1428
1429
1430 //---------------------------------------------------------------
1431 VISU::Result_i
1432 ::~Result_i()
1433 {
1434   MESSAGE("Result_i::~Result_i() - this = "<<this);
1435   if (mySourceId == eRestoredFile) {
1436     static QString aCommand;
1437     aCommand.sprintf("rm %s",myFileInfo.filePath().latin1());
1438     MESSAGE("Result_i::~Result_i - system("<<aCommand<<") = "<<system(aCommand));
1439     aCommand.sprintf("rmdir --ignore-fail-on-non-empty %s",myFileInfo.dirPath().latin1());
1440     MESSAGE("Result_i::~Result_i - system("<<aCommand<<") = "<<system(aCommand));
1441   }
1442   if(myInput) delete myInput;
1443 }
1444
1445 //=======================================================================
1446 //function : GetAxisInfo
1447 //purpose  :
1448 //=======================================================================
1449 const vector< float >* Result_i::GetAxisInfo(const string& theMeshName,
1450                                              TAxis         theAxis,
1451                                              gp_Dir&       thePlaneNormal)
1452 {
1453   const vector< float >* components = NULL;
1454
1455   if ( theAxis < AXIS_X || theAxis > AXIS_Z ) {
1456     MESSAGE(" Bad axis index " << theAxis );
1457     return components;
1458   }
1459
1460   map< string, TGridInfo >::iterator name_info;
1461   name_info = myMeshName2GridInfoMap.find( theMeshName );
1462   TGridInfo * gInfo = 0;
1463
1464   if ( name_info != myMeshName2GridInfoMap.end() )
1465   {
1466     gInfo = & name_info->second;
1467   }
1468   else if ( myInput && IsPossible() && theAxis >= AXIS_X && theAxis <= AXIS_Z )
1469   {
1470     // check presence of theMeshName
1471     const VISU::TMeshMap& meshMap = myInput->GetMeshMap();
1472     if ( meshMap.find( theMeshName ) == meshMap.end() ) {
1473       MESSAGE("No mesh named " << theMeshName );
1474       return components;
1475     }
1476
1477     VISU::PIDMapper anIDMapper = myInput->GetMeshOnEntity(theMeshName,
1478                                                           CELL_ENTITY);
1479     VISU::TVTKOutput* aMesh = anIDMapper->GetVTKOutput();
1480
1481     if ( !aMesh || aMesh->GetNumberOfCells() == 0 ) {
1482       MESSAGE( "No cells in the mesh: " << theMeshName );
1483       return components;
1484     }
1485
1486     // define axis directions and min cell size in each direction
1487     const int nbAxes = 3;
1488     int iAx;
1489     gp_Vec axDirs[ nbAxes ];
1490     float minSize[3] = { FLT_MAX, FLT_MAX, FLT_MAX };
1491     bool axesComputed = false;
1492     for ( vtkIdType iCell = 0; iCell < aMesh->GetNumberOfCells(); ++iCell )
1493     {
1494       vtkCell* cell = aMesh->GetCell( iCell );
1495       int nbPnt = cell->GetNumberOfPoints();
1496       if ( nbPnt != 8 )
1497         continue;
1498       vtkPoints * points = cell->GetPoints();
1499       float* coords[ 4 ];
1500       coords[0] = points->GetPoint( 0 );
1501       coords[1] = points->GetPoint( 1 );
1502       coords[2] = points->GetPoint( 3 );
1503       coords[3] = points->GetPoint( 4 );
1504       gp_Pnt p0( coords[0][0], coords[0][1], coords[0][2] );
1505       for ( iAx = 0; iAx < nbAxes; ++iAx )
1506       {
1507         float* coo = coords[ iAx + 1 ];
1508         gp_Pnt p( coo[0], coo[1], coo[2] );
1509         // min size
1510         float size = p0.SquareDistance( p );
1511         if ( size > FLT_MIN && size < minSize[ iAx ] )
1512           minSize[ iAx ] = size;
1513         // axis direction
1514         if ( !axesComputed ) {
1515           gp_Vec dir( p0, p );
1516           if ( dir.SquareMagnitude() <= DBL_MIN )
1517             break;
1518           axDirs[ iAx ] = dir;
1519         }
1520       }
1521       if ( iAx == nbAxes )
1522         axesComputed = true;
1523     }
1524     if ( !axesComputed ) {
1525       MESSAGE("No good hexahedrons in the mesh: " << theMeshName );
1526       return components;
1527     }
1528
1529     // compute axes dirs
1530     gInfo = & myMeshName2GridInfoMap[ theMeshName ];
1531     for ( iAx = 0; iAx < nbAxes; ++iAx )
1532     {
1533       int iPrev = ( iAx == 0 ) ? 2 : iAx - 1;
1534       int iNext = ( iAx == 2 ) ? 0 : iAx + 1;
1535       gInfo->myAxis[ iAx ] = axDirs[ iPrev ] ^ axDirs[ iNext ];
1536     }
1537
1538     // get and sort intermediate component values - projections of nodes
1539     // on axis direction; define bnd box
1540     set< float > comps[ 3 ];
1541     Bnd_Box box;
1542     vtkPoints * points = aMesh->GetPoints();
1543     vtkIdType iP, nbP = aMesh->GetNumberOfPoints();
1544     for ( iP = 0; iP < nbP; ++iP )
1545     {
1546       float* coo = points->GetPoint( iP );
1547       gp_Pnt p( coo[0], coo[1], coo[2] );
1548       box.Add( p );
1549       for ( iAx = 0; iAx < nbAxes; ++iAx ) {
1550         const gp_Dir& dir = gInfo->myAxis[ iAx ];
1551         float dot = dir.XYZ() * p.XYZ();
1552         comps[ iAx ].insert( dot );
1553       }
1554     }
1555
1556     // find a range of projections of bnd box corners on each axis
1557     float range[3], firstValue[3];
1558     double x[2],y[2],z[2];
1559     box.Get(x[0],y[0],z[0],x[1],y[1],z[1]);
1560     for ( iAx = 0; iAx < nbAxes; ++iAx ) {
1561       set< float > bndComps;
1562       const gp_Dir& dir = gInfo->myAxis[ iAx ];
1563       for ( int iX = 0; iX < 2; ++iX ) {
1564         for ( int iY = 0; iY < 2; ++iY ) {
1565           for ( int iZ = 0; iZ < 2; ++iZ ) {
1566             gp_Pnt p( x[ iX ], y[ iY ], z[ iZ ] );
1567             float dot = dir.XYZ() * p.XYZ();
1568             bndComps.insert( dot );
1569           }
1570         }
1571       }
1572       firstValue[ iAx ] = *bndComps.begin();
1573       range[ iAx ] = *bndComps.rbegin() - *bndComps.begin();
1574     }
1575
1576     // compute component values
1577     for ( iAx = 0; iAx < nbAxes; ++iAx )
1578     {
1579       list< float > values;
1580       int nbVals = 0;
1581       set< float >& comp = comps[ iAx ];
1582       set< float >::iterator val = comp.begin();
1583       float bnd = -1., rng = range[ iAx ], first = firstValue[ iAx ];
1584       float tol = 0.1 * sqrt( minSize[ iAx ]) / rng;
1585       for ( ; val != comp.end(); ++val ) {
1586         float value = ( *val - first ) / rng;
1587         if ( value > bnd ) {
1588           values.push_back( value );
1589           bnd = value + tol;
1590           nbVals++;
1591         }
1592       }
1593       // store values in gInfo
1594       vector< float >& myComp = gInfo->myComponets[ iAx ];
1595       myComp.resize( nbVals );
1596       list< float >::iterator v = values.begin();
1597       for ( int i = 0; v != values.end(); ++v )
1598         myComp[ i++ ] = *v;
1599     }
1600   }
1601
1602   // set return values
1603   if ( gInfo )
1604   {
1605     thePlaneNormal = gInfo->myAxis[ theAxis ];
1606     components = & gInfo->myComponets[ theAxis ];
1607   }
1608
1609   return components;
1610 }