Salome HOME
Join modifications from branch OCC_development_for_3_2_0a2
[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             CORBA::Boolean theIsBuildFields,
792             CORBA::Boolean theIsBuildMinMax,
793             CORBA::Boolean theIsBuildGroups):
794   myStudyDocument(SALOMEDS::Study::_duplicate(theStudy)),
795   myCreationId(theCreationId),
796   mySourceId(theSourceId),
797   myIsBuildImmediately(theIsBuildImmediately),
798   myIsBuildFields(theIsBuildFields),
799   myIsBuildMinMax(theIsBuildMinMax),
800   myIsBuildGroups(theIsBuildGroups),
801   myIsEntitiesDone(false),
802   myIsFieldsDone(false),
803   myIsGroupsDone(false),
804   myIsMinMaxDone(false),
805   myIsAllDone(false),
806   myInput(NULL)
807 {
808   myStudy = ProcessEvent(new TGetStudy(myStudyDocument->StudyId()));
809 }
810
811
812 //---------------------------------------------------------------
813 void
814 VISU::Result_i
815 ::RemoveFromStudy()
816 {
817   struct TRemoveFromStudy: public SALOME_Event
818   {
819     VISU::Result_i* myRemovable;
820     TRemoveFromStudy(VISU::Result_i* theRemovable):
821       myRemovable(theRemovable)
822     {}
823     
824     virtual
825     void
826     Execute()
827     {
828       VISU::RemoveFromStudy(myRemovable->GetSObject(),false);
829       myRemovable->Destroy();
830     }
831   };
832
833   // Remove the result with all presentations and other possible sub-objects
834   ProcessVoidEvent(new TRemoveFromStudy(this));
835 }
836
837
838 //---------------------------------------------------------------
839 void 
840 VISU::Result_i
841 ::MinMaxConnect(VISU::MinMaxCunsomer* theMinMaxCunsomer)
842 {
843   myUpdateMinMaxSignal.connect(boost::bind(&MinMaxCunsomer::UpdateMinMax,theMinMaxCunsomer));
844 }
845
846
847 //---------------------------------------------------------------
848 int
849 VISU::Result_i
850 ::IsPossible()
851 {
852   try{
853     float aSize = myInput->GetSize();
854     bool aResult = VISU_PipeLine::CheckAvailableMemory(aSize);
855     MESSAGE("Result_i::IsPossible - CheckAvailableMemory = "<<float(aSize)<<"; aResult = "<<float(aResult));
856     return aResult;
857   }catch(std::exception& exc){
858     INFOS("Follow exception was occured :\n"<<exc.what());
859   }catch(...){
860     INFOS("Unknown exception was occured!");
861   }
862   return 0;
863 }
864
865
866 //---------------------------------------------------------------
867 CORBA::Boolean
868 VISU::Result_i
869 ::BuildAll()
870 {
871   if(MYDEBUG) MESSAGE("Result_i::Build - myIsAllDone = "<<myIsAllDone);
872   if(myIsAllDone) 
873     return 1;
874   if(!IsPossible()) 
875     return 0;
876   try{
877     const VISU::TMeshMap& aMeshMap = myInput->GetMeshMap();
878     VISU::TMeshMap::const_iterator aMeshMapIter = aMeshMap.begin();
879     for(; aMeshMapIter != aMeshMap.end(); aMeshMapIter++){
880       const string& aMeshName = aMeshMapIter->first;
881       const VISU::PMesh aMesh = aMeshMapIter->second;
882       const VISU::TMeshOnEntityMap& aMeshOnEntityMap = aMesh->myMeshOnEntityMap;
883       VISU::TMeshOnEntityMap::const_iterator aMeshOnEntityMapIter;
884       //Import fields
885       aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
886       for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++){
887         const VISU::TEntity& anEntity = aMeshOnEntityMapIter->first;
888         const VISU::PMeshOnEntity aMeshOnEntity = aMeshOnEntityMapIter->second;
889         const VISU::TFieldMap& aFieldMap = aMeshOnEntity->myFieldMap;
890         VISU::TFieldMap::const_iterator aFieldMapIter = aFieldMap.begin();
891         for(; aFieldMapIter != aFieldMap.end(); aFieldMapIter++){
892           const string& aFieldName = aFieldMapIter->first;
893           const VISU::PField aField = aFieldMapIter->second;
894           const VISU::TValField& aValField = aField->myValField;
895           VISU::TValField::const_iterator aValFieldIter = aValField.begin();
896           for(; aValFieldIter != aValField.end(); aValFieldIter++){
897             int aTimeStamp = aValFieldIter->first;
898             try{
899               myInput->GetTimeStampOnMesh(aMeshName,anEntity,aFieldName,aTimeStamp);
900             }catch(std::exception& exc){
901               INFOS("Follow exception was occured :\n"<<exc.what());
902             }catch(...){
903               INFOS("Unknown exception was occured!!!");
904             }
905           }
906         }
907         //Importing groups
908         const VISU::TGroupMap& aGroupMap = aMesh->myGroupMap;
909         VISU::TGroupMap::const_iterator aGroupMapIter = aGroupMap.begin();
910         for(; aGroupMapIter != aGroupMap.end(); aGroupMapIter++){
911           const string& aGroupName = aGroupMapIter->first;
912           try{
913             myInput->GetMeshOnGroup(aMeshName,aGroupName);
914           }catch(std::exception& exc){
915             INFOS("Follow exception was occured :\n"<<exc.what());
916           }catch(...){
917             INFOS("Unknown exception was occured!!!");
918           }
919         }
920         //Import families
921         const VISU::TFamilyMap& aFamilyMap = aMeshOnEntity->myFamilyMap;
922         VISU::TFamilyMap::const_iterator aFamilyMapIter = aFamilyMap.begin();
923         for(; aFamilyMapIter != aFamilyMap.end(); aFamilyMapIter++){
924           const string& aFamilyName = aFamilyMapIter->first;
925           try{
926             myInput->GetFamilyOnEntity(aMeshName,anEntity,aFamilyName);
927           }catch(std::exception& exc){
928             INFOS("Follow exception was occured :\n"<<exc.what());
929           }catch(...){
930             INFOS("Unknown exception was occured!!!");
931           }
932         }
933         //Import mesh on entity
934         try{
935           myInput->GetMeshOnEntity(aMeshName,anEntity);
936         }catch(std::exception& exc){
937           INFOS("Follow exception was occured :\n"<<exc.what());
938         }catch(...){
939           INFOS("Unknown exception was occured!!!");
940         }
941       }
942     }
943     myIsAllDone = 1;
944   }catch(std::exception& exc){
945     INFOS("Follow exception was occured :\n"<<exc.what());
946   }catch(...){
947     INFOS("Unknown exception was occured!!!");
948   }
949   return myIsAllDone;
950 }
951
952
953 //---------------------------------------------------------------
954 CORBA::Boolean
955 VISU::Result_i
956 ::Build(CORBA::Boolean theIsBuildAll,
957         CORBA::Boolean theIsAtOnce)
958 {
959   if(theIsBuildAll)
960     theIsAtOnce = true;
961
962   if(Build(SALOMEDS::SObject::_nil(),theIsAtOnce)){
963     if(theIsBuildAll)
964       return BuildAll();
965     return true;
966   }
967
968   return false;
969 }
970
971
972 //---------------------------------------------------------------
973 VISU::Storable*
974 VISU::Result_i
975 ::Build(SALOMEDS::SObject_ptr theSObject,
976         CORBA::Boolean theIsAtOnce)
977 {
978   if(!myInput)
979     return NULL;
980
981   if(IsDone())
982     return this;
983
984   mySComponent = FindOrCreateVisuComponent(myStudyDocument);
985   CORBA::String_var aSComponentEntry = mySComponent->GetID();
986   CORBA::String_var anIOR(GetID());
987   QString aComment;
988   aComment.sprintf("myComment=%s;myType=%d;myFileName=%s;myInitFileName=%s",
989                    GetComment(),
990                    VISU::TRESULT,
991                    myFileInfo.filePath().latin1(),
992                    myInitFileName.c_str()); // Restoring of Python dump
993   string aResultEntry =
994     CreateAttributes(myStudy,
995                      aSComponentEntry.in(),
996                      anIOR.in(),
997                      myName,
998                      "",
999                      aComment.latin1(),
1000                      true);
1001   mySObject = myStudyDocument->FindObjectID(aResultEntry.c_str());
1002   if(!CORBA::is_nil(theSObject)){
1003     CORBA::String_var aString = theSObject->GetID();
1004     CreateReference(myStudyDocument,aResultEntry,aString.in());
1005   }
1006
1007   if(theIsAtOnce){
1008     BuildEntities(this,
1009                   myInput,
1010                   &myIsEntitiesDone,
1011                   aResultEntry,
1012                   myStudy);
1013     
1014     BuildGroups(this,
1015                 myInput,
1016                 &myIsGroupsDone,
1017                 myIsBuildGroups,
1018                 myStudy);
1019
1020     BuildFields(this,
1021                 myInput,
1022                 &myIsFieldsDone,
1023                 myIsBuildFields,
1024                 myStudy);
1025     
1026     BuildMinMax(this,
1027                 myInput,
1028                 &myIsMinMaxDone,
1029                 myIsBuildMinMax,
1030                 &myUpdateMinMaxSignal);
1031     
1032   }else{
1033     TBuildArgs aBuildArgs(this,
1034                           myInput,
1035                           &myIsEntitiesDone,
1036                           aResultEntry,
1037                           &myIsFieldsDone,
1038                           myIsBuildFields,
1039                           &myIsMinMaxDone,
1040                           myIsBuildMinMax,
1041                           &myUpdateMinMaxSignal,
1042                           &myIsGroupsDone,
1043                           myIsBuildGroups,
1044                           myStudy);
1045     boost::thread aThread(boost::bind(&BuildDataTree,
1046                                       aBuildArgs));
1047   }
1048
1049   return this;
1050 }
1051
1052
1053 //---------------------------------------------------------------
1054 VISU::Storable*
1055 VISU::Result_i
1056 ::BuildAll(SALOMEDS::SObject_ptr theSObject)
1057 {
1058   if(MYDEBUG) MESSAGE("Result_i::Build");
1059   try{
1060     Build(theSObject);
1061     BuildAll();
1062   }catch(std::exception& exc){
1063     INFOS("Follow exception was occured :\n"<<exc.what());
1064     return NULL;
1065   }catch(...){
1066     INFOS("Unknown exception was occured!!!");
1067     return NULL;
1068   }
1069
1070   return this;
1071 }
1072
1073
1074 //---------------------------------------------------------------
1075 VISU::Storable*
1076 VISU::Result_i::
1077 Create(const char* theFileName)
1078 {
1079   try{
1080     myFileInfo.setFile(theFileName);
1081     myInitFileName = myFileInfo.filePath().latin1();
1082     myName = ::GenerateName(myFileInfo.fileName()).latin1();
1083     if(mySourceId == eRestoredFile){
1084       std::string aTmpDir(SALOMEDS_Tool::GetTmpDir());
1085       static QString aCommand;
1086       aCommand.sprintf("cp %s %s",myFileInfo.absFilePath().latin1(),aTmpDir.c_str());
1087       if(system(aCommand) == -1){
1088         MESSAGE("Create - Can't execute the command :"<<aCommand);
1089         return NULL;
1090       }
1091       if(MYDEBUG) MESSAGE("Result_i::Create - aCommand = "<<aCommand);
1092       myFileInfo.setFile(QString(aTmpDir.c_str()) + myFileInfo.fileName());
1093     }
1094     myInput = CreateConvertor(myFileInfo.absFilePath().latin1());
1095     if(myInput){
1096       if(myIsBuildImmediately)
1097         Build(SALOMEDS::SObject::_nil());
1098       return this;
1099     }
1100   }catch(std::exception& exc){
1101     INFOS("Follow exception was occured :\n"<<exc.what());
1102   }catch(...){
1103     INFOS("Unknown exception was occured!!!");
1104   }
1105   return NULL;
1106 }
1107
1108
1109 //---------------------------------------------------------------
1110 VISU::Storable*
1111 VISU::Result_i::
1112 Create(SALOMEDS::SObject_ptr theMedSObject)
1113 {
1114   if(MYDEBUG)  MESSAGE("Result_i::Create MedObject from SALOMEDS::SObject_ptr");
1115   try{
1116     myInput = CreateMEDConvertor(theMedSObject);
1117     if(myInput == NULL)
1118       return NULL;
1119
1120     myInput->Build();
1121
1122     string aCompDataType = GetComponentDataType(theMedSObject);
1123     myFileInfo.setFile(aCompDataType.c_str());
1124     myInitFileName = aCompDataType;
1125
1126     myName = ::GenerateName("aResult").latin1();
1127
1128     return Build(theMedSObject);
1129   }catch(std::exception& exc){
1130     INFOS("Follow exception was occured :\n"<<exc.what());
1131   }catch(...){
1132     INFOS("Unknown exception was occured!!!");
1133   }
1134   return NULL;
1135 }
1136
1137
1138 //---------------------------------------------------------------
1139 VISU::Storable*
1140 VISU::Result_i::
1141 Create(SALOME_MED::FIELD_ptr theField)
1142 {
1143   if(MYDEBUG)  MESSAGE("Result_i::Create MedObject from SALOME_MED::FIELD_ptr");
1144   try{
1145     myInput = CreateMEDFieldConvertor(theField);
1146     if(myInput == NULL)
1147       return NULL;
1148
1149     myInput->Build();
1150
1151     string aCompDataType = "MED";
1152     myFileInfo.setFile(aCompDataType.c_str());
1153     myInitFileName = aCompDataType;
1154
1155     myName = ::GenerateName("aResult").latin1();
1156
1157     CORBA::String_var anIOR = myStudyDocument->ConvertObjectToIOR(theField);
1158     SALOMEDS::SObject_var aFieldSObject = myStudyDocument->FindObjectIOR(anIOR);
1159
1160     return Build(aFieldSObject);
1161   }catch(std::exception& exc){
1162     INFOS("Follow exception was occured :\n"<<exc.what());
1163   }catch(...){
1164     INFOS("Unknown exception was occured!!!");
1165   }
1166   return NULL;
1167 }
1168
1169
1170 //---------------------------------------------------------------
1171 VISU::Storable*
1172 VISU::Result_i::
1173 Restore(SALOMEDS::SObject_ptr theSObject,
1174         const Storable::TRestoringMap& theMap,
1175         const string& thePrefix)
1176 {
1177   if(MYDEBUG) MESSAGE("Result_i::Restore - " << thePrefix);
1178   try {
1179     mySObject = SALOMEDS::SObject::_duplicate(theSObject);
1180     myStudyDocument = mySObject->GetStudy();
1181     mySComponent = mySObject->GetFatherComponent();
1182     myName = VISU::Storable::FindValue(theMap, "myName").latin1();
1183     myInitFileName = VISU::Storable::FindValue(theMap, "myInitFileName").latin1();
1184
1185     SALOMEDS::SObject_var aRefSObj, aTargetRefSObj;
1186     if (mySObject->FindSubObject(1, aRefSObj) &&
1187         aRefSObj->ReferencedObject(aTargetRefSObj)) 
1188     {
1189       if(MYDEBUG) MESSAGE("Result_i::GetInput - There is some reference.");
1190       SALOMEDS::SComponent_var aCompRefSObj = aTargetRefSObj->GetFatherComponent();
1191       CORBA::String_var aDataType = aCompRefSObj->ComponentDataType();
1192       myFileInfo.setFile(aDataType.in());
1193       if(MYDEBUG) MESSAGE("Result_i::GetInput - aDataType = " << aDataType);
1194       Engines::Component_var aEngComp =
1195         Base_i::myEnginesLifeCycle->FindOrLoad_Component("FactoryServer", aDataType.in());
1196       if (CORBA::is_nil(aEngComp))
1197         throw std::runtime_error("Restore - There is no aEngComp for the aDataType !!!");
1198       SALOMEDS::StudyBuilder_var aStudyBuilder = myStudyDocument->NewBuilder();
1199       SALOMEDS::Driver_var aDriver = SALOMEDS::Driver::_narrow(aEngComp);
1200       aStudyBuilder->LoadWith(aCompRefSObj, aDriver);
1201       if (strcmp(aDataType, "MED") == 0){
1202         // create field or MED converter
1203         CORBA::Object_var aMedObject = VISU::SObjectToObject(aTargetRefSObj);
1204         SALOME_MED::FIELD_var aField = SALOME_MED::FIELD::_narrow(aMedObject);
1205         if(!CORBA::is_nil(aField))
1206           myInput = CreateMEDFieldConvertor(aField);
1207         else
1208           myInput = CreateMEDConvertor(aTargetRefSObj);
1209         myInput->Build();
1210       }else
1211         throw std::runtime_error("GetInput - There is no convertor for the aDataType !!!");
1212     } else {
1213       myFileInfo.setFile(thePrefix.c_str());
1214
1215       string aStudyPrefix ("");
1216       if (IsMultifile())
1217         aStudyPrefix = SALOMEDS_Tool::GetNameFromPath(myStudyDocument->URL());
1218       if (!myFileInfo.isFile()) {
1219         string aFileName = thePrefix + aStudyPrefix + "_" + myName;
1220         myFileInfo.setFile(aFileName.c_str());
1221       }
1222       if(MYDEBUG)
1223         MESSAGE("Result_i::Restore - aFileName = " << myFileInfo.filePath() << "; " << myFileInfo.isFile());
1224
1225       const char* aPathLatin = myFileInfo.filePath().latin1();
1226       if (HDFascii::isASCII(aPathLatin)) {
1227         MESSAGE("ConvertFromASCIIToHDF(" << aPathLatin << ")");
1228         char* aResultPath = HDFascii::ConvertFromASCIIToHDF(aPathLatin);
1229         MESSAGE("ConvertFromASCIIToHDF() DONE : " << aResultPath);
1230         char* aHDFFileName = new char[strlen(aResultPath) + 19];
1231         sprintf(aHDFFileName, "%shdf_from_ascii.hdf", aResultPath);
1232
1233         if (IsMultifile()) { // set this file as new - temporary
1234           static QString aCommand;
1235           aCommand.sprintf("mv %s %s%s",aHDFFileName, aResultPath, myFileInfo.baseName().latin1());
1236           if (system(aCommand) == -1) {
1237             if(MYDEBUG) MESSAGE("VISU::Result_i::Restore - Can't execute the command :" << aCommand);
1238             return NULL;
1239           } else {
1240             if(MYDEBUG) MESSAGE("VISU::Result_i::Restore - " << aCommand);
1241           }
1242           myFileInfo.setFile(QString(aResultPath) + QString(myFileInfo.baseName().latin1()));
1243         } else { // change current temporary file to the new: with hdf-format
1244           static QString aCommand;
1245           aCommand.sprintf("mv %s %s\0",aHDFFileName, myFileInfo.filePath().latin1());
1246           if (system(aCommand.latin1()) == -1) {
1247             if(MYDEBUG) MESSAGE("VISU::Result_i::Restore - Can't execute the command :" << aCommand);
1248             return NULL;
1249           } else {
1250             if(MYDEBUG) MESSAGE("VISU::Result_i::Restore - " << aCommand);
1251           }
1252           SALOMEDS::ListOfFileNames_var anEmptyList = new SALOMEDS::ListOfFileNames;
1253           SALOMEDS_Tool::RemoveTemporaryFiles(aResultPath, anEmptyList.in(), true);
1254         }
1255         mySourceId = eRestoredFile;
1256         delete(aResultPath);
1257         delete(aHDFFileName);
1258       } else if (!IsMultifile()) {
1259         mySourceId = eRestoredFile;
1260       } else {
1261         mySourceId = eFile;
1262       }
1263       if(MYDEBUG) MESSAGE("VISU::Result_i::Restore - mySourceId = " << mySourceId);
1264       myInput = CreateConvertor(myFileInfo.filePath().latin1());
1265
1266       myInput->BuildEntities();
1267       if(myIsBuildFields){
1268         myInput->BuildFields();
1269         myIsFieldsDone = true;
1270         if(myIsBuildMinMax){
1271           myInput->BuildMinMax();
1272           myIsMinMaxDone = true;
1273         }
1274       }
1275       if(myIsBuildGroups){
1276         myInput->BuildGroups();
1277         myIsGroupsDone = true;
1278       }
1279
1280       QString aComment;
1281       aComment.sprintf("myComment=%s;myType=%d;myFileName=%s;myInitFileName=%s",
1282                        GetComment(), VISU::TRESULT, myFileInfo.filePath().latin1(),
1283                        myInitFileName.c_str()); // Restoring of Python dump
1284       SALOMEDS::GenericAttribute_var anAttr;
1285       if (!theSObject->FindAttribute(anAttr, "AttributeComment"))
1286         throw std::runtime_error("Build - There is no AttributeComment for the SObject !!!");
1287       SALOMEDS::AttributeComment_var aCmnt = SALOMEDS::AttributeComment::_narrow(anAttr);
1288       aCmnt->SetValue(aComment.latin1());
1289     }
1290     bool anIsBuildAll = VISU::GetResourceMgr()->booleanValue("VISU", "full_med_loading", false);
1291     if(anIsBuildAll)
1292       BuildAll();
1293     return this;
1294   } catch(std::exception& exc) {
1295     INFOS("Follow exception was occured :\n"<<exc.what());
1296   } catch(...) {
1297     INFOS("Unknown exception was occured!!!");
1298   }
1299   return NULL;
1300 }
1301
1302 //---------------------------------------------------------------
1303 VISU::Result_i::TInput* 
1304 VISU::Result_i
1305 ::GetInput() 
1306 {
1307   return myInput;
1308 }
1309
1310 //---------------------------------------------------------------
1311 CORBA::Boolean 
1312 VISU::Result_i
1313 ::IsDone() 
1314 {
1315   return 
1316     myIsEntitiesDone && 
1317     (myIsBuildFields? myIsFieldsDone: true) &&
1318     (myIsBuildMinMax? myIsMinMaxDone: true) &&
1319     (myIsBuildGroups? myIsGroupsDone: true);
1320 }
1321
1322 CORBA::Boolean 
1323 VISU::Result_i
1324 ::IsEntitiesDone() 
1325 {
1326   return myIsEntitiesDone;
1327 }
1328
1329 void
1330 VISU::Result_i
1331 ::SetBuildFields(CORBA::Boolean theIsBuildFields, 
1332                  CORBA::Boolean theIsCalculateMinMax)
1333 {
1334   myIsBuildFields = theIsBuildFields;
1335   if(theIsBuildFields)
1336     myIsBuildMinMax = theIsCalculateMinMax;
1337   else
1338     myIsBuildMinMax = false;
1339 }
1340
1341 void
1342 VISU::Result_i
1343 ::SetBuildGroups(CORBA::Boolean theIsBuildGroups)
1344 {
1345   myIsBuildGroups = theIsBuildGroups;
1346 }
1347
1348 CORBA::Boolean 
1349 VISU::Result_i
1350 ::IsFieldsDone() 
1351 {
1352   return myIsFieldsDone;
1353 }
1354
1355 CORBA::Boolean 
1356 VISU::Result_i
1357 ::IsGroupsDone() 
1358 {
1359   return myIsGroupsDone;
1360 }
1361
1362 CORBA::Boolean 
1363 VISU::Result_i
1364 ::IsMinMaxDone() 
1365 {
1366   return myIsMinMaxDone;
1367 }
1368
1369 //---------------------------------------------------------------
1370 void 
1371 VISU::Result_i
1372 ::ToStream(std::ostringstream& theStr)
1373 {
1374   if(MYDEBUG) MESSAGE(GetComment());
1375   Storable::DataToStream(theStr,"myName",myName.c_str());
1376   Storable::DataToStream(theStr,"myInitFileName",myInitFileName.c_str());
1377   Storable::DataToStream(theStr,"myCreationId",myCreationId);
1378   Storable::DataToStream(theStr,"myIsBuildFields",myIsFieldsDone);
1379   Storable::DataToStream(theStr,"myIsBuildMinMax",myIsMinMaxDone);
1380   Storable::DataToStream(theStr,"myIsBuildGroups",myIsGroupsDone);
1381 }
1382
1383
1384 //---------------------------------------------------------------
1385 VISU::Storable*
1386 VISU::Result_i
1387 ::Restore(SALOMEDS::SObject_ptr theSObject,
1388           const string& thePrefix,
1389           const Storable::TRestoringMap& theMap)
1390 {
1391   SALOMEDS::Study_var aStudy = theSObject->GetStudy();
1392
1393   ECreationId aCreationId = ECreationId(Storable::FindValue(theMap,"myCreationId").toInt());
1394   ESourceId aSourceId = eRestoredFile;
1395   if(aCreationId == eImportMed || aCreationId == eImportMedField)
1396     aSourceId = eRestoredComponent;
1397
1398   CORBA::Boolean anIsBuildFields = Storable::FindValue(theMap,"myIsBuildFields","0").toInt();
1399   CORBA::Boolean anIsBuildMinMax = Storable::FindValue(theMap,"myIsBuildMinMax","0").toInt();
1400   CORBA::Boolean anIsBuildGroups = Storable::FindValue(theMap,"myIsBuildGroups","0").toInt();
1401
1402   VISU::Result_i* aResult = new VISU::Result_i(aStudy,
1403                                                aSourceId,
1404                                                aCreationId,
1405                                                anIsBuildFields,
1406                                                anIsBuildMinMax,
1407                                                anIsBuildGroups);
1408   if (aResult == NULL)
1409     return NULL;
1410
1411   return aResult->Restore(theSObject,theMap,thePrefix);
1412 }
1413
1414
1415 //---------------------------------------------------------------
1416 string 
1417 VISU::Result_i
1418 ::GetRefFatherEntry() 
1419 {
1420   return "";
1421 }
1422
1423 string
1424 VISU::Result_i
1425 ::GetEntry()
1426 {
1427   CORBA::String_var anEntry = mySObject->GetID();
1428   return string(anEntry);
1429 }
1430
1431 const SALOMEDS::SObject_var& 
1432 VISU::Result_i
1433 ::GetSObject() const 
1434
1435   return mySObject;
1436 }
1437
1438 const SALOMEDS::Study_var& 
1439 VISU::Result_i
1440 ::GetStudyDocument() const 
1441
1442   return myStudyDocument;
1443 }
1444
1445 const SALOMEDS::SComponent_var& 
1446 VISU::Result_i
1447 ::GetSComponent() const
1448 {
1449   return mySComponent;
1450 }
1451
1452 std::string 
1453 VISU::Result_i
1454 ::GetEntry(const std::string& theComment)
1455 {
1456   return FindEntryWithComment(myStudyDocument,GetEntry().c_str(),theComment.c_str());
1457 }
1458
1459
1460 //---------------------------------------------------------------
1461 VISU::Result_i
1462 ::~Result_i()
1463 {
1464   MESSAGE("Result_i::~Result_i() - this = "<<this);
1465   if (mySourceId == eRestoredFile) {
1466     static QString aCommand;
1467     aCommand.sprintf("rm %s",myFileInfo.filePath().latin1());
1468     MESSAGE("Result_i::~Result_i - system("<<aCommand<<") = "<<system(aCommand));
1469     aCommand.sprintf("rmdir --ignore-fail-on-non-empty %s",myFileInfo.dirPath().latin1());
1470     MESSAGE("Result_i::~Result_i - system("<<aCommand<<") = "<<system(aCommand));
1471   }
1472   if(myInput) delete myInput;
1473 }
1474
1475 //=======================================================================
1476 //function : GetAxisInfo
1477 //purpose  :
1478 //=======================================================================
1479 const vector< float >* Result_i::GetAxisInfo(const string& theMeshName,
1480                                              TAxis         theAxis,
1481                                              gp_Dir&       thePlaneNormal)
1482 {
1483   const vector< float >* components = NULL;
1484
1485   if ( theAxis < AXIS_X || theAxis > AXIS_Z ) {
1486     MESSAGE(" Bad axis index " << theAxis );
1487     return components;
1488   }
1489
1490   map< string, TGridInfo >::iterator name_info;
1491   name_info = myMeshName2GridInfoMap.find( theMeshName );
1492   TGridInfo * gInfo = 0;
1493
1494   if ( name_info != myMeshName2GridInfoMap.end() )
1495   {
1496     gInfo = & name_info->second;
1497   }
1498   else if ( myInput && IsPossible() && theAxis >= AXIS_X && theAxis <= AXIS_Z )
1499   {
1500     // check presence of theMeshName
1501     const VISU::TMeshMap& meshMap = myInput->GetMeshMap();
1502     if ( meshMap.find( theMeshName ) == meshMap.end() ) {
1503       MESSAGE("No mesh named " << theMeshName );
1504       return components;
1505     }
1506
1507     VISU::PIDMapper anIDMapper = myInput->GetMeshOnEntity(theMeshName,
1508                                                           CELL_ENTITY);
1509     VISU::TVTKOutput* aMesh = anIDMapper->GetVTKOutput();
1510
1511     if ( !aMesh || aMesh->GetNumberOfCells() == 0 ) {
1512       MESSAGE( "No cells in the mesh: " << theMeshName );
1513       return components;
1514     }
1515
1516     // define axis directions and min cell size in each direction
1517     const int nbAxes = 3;
1518     int iAx;
1519     gp_Vec axDirs[ nbAxes ];
1520     float minSize[3] = { FLT_MAX, FLT_MAX, FLT_MAX };
1521     bool axesComputed = false;
1522     for ( vtkIdType iCell = 0; iCell < aMesh->GetNumberOfCells(); ++iCell )
1523     {
1524       vtkCell* cell = aMesh->GetCell( iCell );
1525       int nbPnt = cell->GetNumberOfPoints();
1526       if ( nbPnt != 8 )
1527         continue;
1528       vtkPoints * points = cell->GetPoints();
1529       float* coords[ 4 ];
1530       coords[0] = points->GetPoint( 0 );
1531       coords[1] = points->GetPoint( 1 );
1532       coords[2] = points->GetPoint( 3 );
1533       coords[3] = points->GetPoint( 4 );
1534       gp_Pnt p0( coords[0][0], coords[0][1], coords[0][2] );
1535       for ( iAx = 0; iAx < nbAxes; ++iAx )
1536       {
1537         float* coo = coords[ iAx + 1 ];
1538         gp_Pnt p( coo[0], coo[1], coo[2] );
1539         // min size
1540         float size = p0.SquareDistance( p );
1541         if ( size > FLT_MIN && size < minSize[ iAx ] )
1542           minSize[ iAx ] = size;
1543         // axis direction
1544         if ( !axesComputed ) {
1545           gp_Vec dir( p0, p );
1546           if ( dir.SquareMagnitude() <= DBL_MIN )
1547             break;
1548           axDirs[ iAx ] = dir;
1549         }
1550       }
1551       if ( iAx == nbAxes )
1552         axesComputed = true;
1553     }
1554     if ( !axesComputed ) {
1555       MESSAGE("No good hexahedrons in the mesh: " << theMeshName );
1556       return components;
1557     }
1558
1559     // compute axes dirs
1560     gInfo = & myMeshName2GridInfoMap[ theMeshName ];
1561     for ( iAx = 0; iAx < nbAxes; ++iAx )
1562     {
1563       int iPrev = ( iAx == 0 ) ? 2 : iAx - 1;
1564       int iNext = ( iAx == 2 ) ? 0 : iAx + 1;
1565       gInfo->myAxis[ iAx ] = axDirs[ iPrev ] ^ axDirs[ iNext ];
1566     }
1567
1568     // get and sort intermediate component values - projections of nodes
1569     // on axis direction; define bnd box
1570     set< float > comps[ 3 ];
1571     Bnd_Box box;
1572     vtkPoints * points = aMesh->GetPoints();
1573     vtkIdType iP, nbP = aMesh->GetNumberOfPoints();
1574     for ( iP = 0; iP < nbP; ++iP )
1575     {
1576       float* coo = points->GetPoint( iP );
1577       gp_Pnt p( coo[0], coo[1], coo[2] );
1578       box.Add( p );
1579       for ( iAx = 0; iAx < nbAxes; ++iAx ) {
1580         const gp_Dir& dir = gInfo->myAxis[ iAx ];
1581         float dot = dir.XYZ() * p.XYZ();
1582         comps[ iAx ].insert( dot );
1583       }
1584     }
1585
1586     // find a range of projections of bnd box corners on each axis
1587     float range[3], firstValue[3];
1588     double x[2],y[2],z[2];
1589     box.Get(x[0],y[0],z[0],x[1],y[1],z[1]);
1590     for ( iAx = 0; iAx < nbAxes; ++iAx ) {
1591       set< float > bndComps;
1592       const gp_Dir& dir = gInfo->myAxis[ iAx ];
1593       for ( int iX = 0; iX < 2; ++iX ) {
1594         for ( int iY = 0; iY < 2; ++iY ) {
1595           for ( int iZ = 0; iZ < 2; ++iZ ) {
1596             gp_Pnt p( x[ iX ], y[ iY ], z[ iZ ] );
1597             float dot = dir.XYZ() * p.XYZ();
1598             bndComps.insert( dot );
1599           }
1600         }
1601       }
1602       firstValue[ iAx ] = *bndComps.begin();
1603       range[ iAx ] = *bndComps.rbegin() - *bndComps.begin();
1604     }
1605
1606     // compute component values
1607     for ( iAx = 0; iAx < nbAxes; ++iAx )
1608     {
1609       list< float > values;
1610       int nbVals = 0;
1611       set< float >& comp = comps[ iAx ];
1612       set< float >::iterator val = comp.begin();
1613       float bnd = -1., rng = range[ iAx ], first = firstValue[ iAx ];
1614       float tol = 0.1 * sqrt( minSize[ iAx ]) / rng;
1615       for ( ; val != comp.end(); ++val ) {
1616         float value = ( *val - first ) / rng;
1617         if ( value > bnd ) {
1618           values.push_back( value );
1619           bnd = value + tol;
1620           nbVals++;
1621         }
1622       }
1623       // store values in gInfo
1624       vector< float >& myComp = gInfo->myComponets[ iAx ];
1625       myComp.resize( nbVals );
1626       list< float >::iterator v = values.begin();
1627       for ( int i = 0; v != values.end(); ++v )
1628         myComp[ i++ ] = *v;
1629     }
1630   }
1631
1632   // set return values
1633   if ( gInfo )
1634   {
1635     thePlaneNormal = gInfo->myAxis[ theAxis ];
1636     components = & gInfo->myComponets[ theAxis ];
1637   }
1638
1639   return components;
1640 }