Salome HOME
Join modifications from branch OCC_development_for_3_2_0a2
[modules/visu.git] / src / VISU_I / VISU_Result_i.cc
index 359aea091d4f8d62c4c04eecd392897060ea3b11..9745df0151ee25f8c58b112988c278ff423ef07f 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "VISU_Convertor_impl.hxx"
 #include "VISU_CorbaMedConvertor.hxx"
+#include "VISU_ConvertorUtils.hxx"
 #include "VISU_PipeLine.hxx"
 
 #include "SUIT_ResourceMgr.h"
 #include "SALOMEDS_Tool.hxx"
 #include "HDFascii.hxx"
 
+#include "SUIT_Session.h"
+#include "SALOME_Event.hxx"
+#include "SalomeApp_Study.h"
+#include "SalomeApp_Application.h"
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/thread.hpp>
+
+#include <boost/thread/mutex.hpp>
+#include <boost/bind.hpp>
+
 // QT Includes
 #include <qstring.h>
 #include <qfileinfo.h>
+#include <qsemaphore.h>
+#include <qthread.h>
 
 // VTK Includes
 #include <vtkCell.h>
@@ -51,101 +65,789 @@ using namespace std;
 
 #ifdef _DEBUG_
 static int MYDEBUG = 0;
+static int MYTIMEDEBUG = 0;
 #else
 static int MYDEBUG = 0;
+static int MYTIMEDEBUG = 0;
 #endif
 
-VISU::Result_var VISU::FindResult (SALOMEDS::SObject_ptr theSObject)
+
+namespace VISU
 {
-  SALOMEDS::SComponent_var aSComponent = theSObject->GetFatherComponent();
-  SALOMEDS::SObject_var aFather = theSObject->GetFather();
-  CORBA::String_var aComponentID (aSComponent->GetID());
-  CORBA::String_var aFatherID    (aFather->GetID());
-  VISU::Result_var aResult;
-  while (strcmp(aComponentID, aFatherID) != 0) {
-    CORBA::Object_var anObject = VISU::SObjectToObject(aFather);
-    if (!CORBA::is_nil(anObject)) {
-      aResult = VISU::Result::_narrow(anObject);
-      if (!aResult->_is_nil()) return aResult;
-    }
-    aFather = aFather->GetFather();
-    aFatherID = aFather->GetID();
+  //---------------------------------------------------------------
+  Result_var 
+  FindResult (SALOMEDS::SObject_ptr theSObject)
+  {
+    SALOMEDS::SComponent_var aSComponent = theSObject->GetFatherComponent();
+    SALOMEDS::SObject_var aFather = theSObject->GetFather();
+    CORBA::String_var aComponentID (aSComponent->GetID());
+    CORBA::String_var aFatherID    (aFather->GetID());
+    Result_var aResult;
+    while (strcmp(aComponentID, aFatherID) != 0) {
+      CORBA::Object_var anObject = SObjectToObject(aFather);
+      if (!CORBA::is_nil(anObject)) {
+       aResult = Result::_narrow(anObject);
+       if (!aResult->_is_nil()) return aResult;
+      }
+      aFather = aFather->GetFather();
+      aFatherID = aFather->GetID();
+    }
+    return aResult;
   }
-  return aResult;
-}
 
-QString GenerateName (const char* theName)
-{
-  typedef map<string,int> TNameMap;
-  static TNameMap aMap;
-  TNameMap::const_iterator i = aMap.find(theName);
-  QString tmp;
-  if (i == aMap.end()) {
-    aMap[theName] = 0;
-    tmp = theName;
-  } else {
-    tmp = VISU::GenerateName(theName,++aMap[theName]);
+
+  //---------------------------------------------------------------
+  typedef boost::recursive_mutex TMutex;
+  typedef TMutex::scoped_lock TLock;
+
+  static TMutex myMutex;
+
+  //---------------------------------------------------------------
+  struct TGetStudy: public SALOME_Event
+  {
+    typedef _PTR(Study) TResult;
+    TResult myResult;
+    int myStudyId;
+
+    TGetStudy(const int theStudyId):
+      myStudyId(theStudyId)
+    {}
+    
+    virtual
+    void
+    Execute()
+    {
+      SUIT_Session* aSession = SUIT_Session::session();
+      QPtrList<SUIT_Application> anApplications = aSession->applications();
+      QPtrListIterator<SUIT_Application> anIter (anApplications);
+      while (SUIT_Application* aSApp = anIter.current()) {
+       if(SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>(aSApp)){
+         if(SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(anApp->activeStudy())) {
+           if(_PTR(Study) aStudyDS = aStudy->studyDS()){
+             if(aStudyDS->StudyId() == myStudyId){
+               myResult = aStudy->studyDS();
+               break;
+             }
+           }
+         }
+       }
+       ++anIter;
+      }
+    }
+  };
+
+
+  //---------------------------------------------------------------
+  QString
+  GenerateName (const char* theName)
+  {
+    TLock aLock(myMutex);
+
+    typedef map<string,int> TNameMap;
+    static TNameMap aMap;
+
+    TNameMap::const_iterator i = aMap.find(theName);
+    QString tmp;
+    if (i == aMap.end()) {
+      aMap[theName] = 0;
+      tmp = theName;
+    } else {
+      tmp = GenerateName(theName,++aMap[theName]);
+    }
+    if(MYDEBUG) MESSAGE("GenerateName - "<<tmp<<" from - "<<theName<<"; " <<aMap[theName]);
+    return tmp;
   }
-  if(MYDEBUG) MESSAGE("GenerateName - "<<tmp<<" from - "<<theName<<"; " <<aMap[theName]);
-  return tmp;
-}
+  
 
-QString GenerateFieldName (const string& theName, const string& theUnits)
-{
-  static QString aName;
-  const string tmp (theUnits.size(),' ');
-  if (theUnits == "" || theUnits == tmp)
-    aName.sprintf("%s, -",theName.c_str());
-  else
-    aName.sprintf("%s, %s",theName.c_str(),theUnits.c_str());
-  aName = aName.simplifyWhiteSpace();
-  return aName.latin1();
+  //---------------------------------------------------------------
+  QString 
+  GenerateFieldName (const string& theName, const string& theUnits)
+  {
+    QString aName;
+    const string tmp (theUnits.size(),' ');
+    if (theUnits == "" || theUnits == tmp)
+      aName.sprintf("%s, -",theName.c_str());
+    else
+      aName.sprintf("%s, %s",theName.c_str(),theUnits.c_str());
+    aName = aName.simplifyWhiteSpace();
+    return aName.latin1();
+  }
+
+
+  //---------------------------------------------------------------
+  string
+  GetComponentDataType (SALOMEDS::SObject_ptr theSObject)
+  {
+    SALOMEDS::SComponent_var aCompRefSObj = theSObject->GetFatherComponent();
+    CORBA::String_var aDataType = aCompRefSObj->ComponentDataType();
+    return aDataType.in();
+  }
+
+
+  //---------------------------------------------------------------
+  void
+  CreateReference (SALOMEDS::Study_ptr theStudyDocument,
+                  const string& theFatherEntry, 
+                  const string& theRefEntry)
+  {
+    SALOMEDS::StudyBuilder_var aStudyBuilder = theStudyDocument->NewBuilder();
+    SALOMEDS::SObject_var aFather = theStudyDocument->FindObjectID(theFatherEntry.c_str());
+    SALOMEDS::SObject_var newObj = aStudyBuilder->NewObject(aFather);
+    SALOMEDS::SObject_var aRefSObj = theStudyDocument->FindObjectID(theRefEntry.c_str());
+    aStudyBuilder->Addreference(newObj,aRefSObj);
+  }
+
+
+  //---------------------------------------------------------------
+  void
+  CreateReference (_PTR(Study) theStudyDocument,
+                  const string& theFatherEntry, 
+                  const string& theRefEntry)
+  {
+    TLock aLock(myMutex);
+
+    _PTR(StudyBuilder) aStudyBuilder = theStudyDocument->NewBuilder();
+    _PTR(SObject) aFather = theStudyDocument->FindObjectID(theFatherEntry);
+    _PTR(SObject) aNewObj = aStudyBuilder->NewObject(aFather);
+    _PTR(SObject) aRefSObj = theStudyDocument->FindObjectID(theRefEntry);
+    aStudyBuilder->Addreference(aNewObj,aRefSObj);
+  }
+
+  string 
+  CreateAttributes(_PTR(Study) theStudyDocument,
+                  const string& theFatherEntry, 
+                  const string& theIOR, 
+                  const string& theName,
+                  const string& thePersistentRef, 
+                  const string& theComment,
+                  CORBA::Boolean theCreateNew)
+  {
+    TLock aLock(myMutex);
+
+    _PTR(StudyBuilder) aStudyBuilder = theStudyDocument->NewBuilder();
+    _PTR(SObject) aFather = theStudyDocument->FindObjectID(theFatherEntry);
+
+    _PTR(SObject) aNewObj;
+    if(theCreateNew)
+      aNewObj = aStudyBuilder->NewObject(aFather);
+    else
+      aNewObj = aFather;
+
+    _PTR(GenericAttribute) anAttr;
+    if (theIOR != "") {
+      anAttr = aStudyBuilder->FindOrCreateAttribute(aNewObj, "AttributeIOR");
+      _PTR(AttributeIOR) anIOR (anAttr);
+      anIOR->SetValue(theIOR);
+    }
+    if (theName != "") {
+      anAttr = aStudyBuilder->FindOrCreateAttribute(aNewObj, "AttributeName");
+      _PTR(AttributeName) aName (anAttr);
+      aName->SetValue(theName);
+    }
+    if (thePersistentRef != "") {
+      anAttr = aStudyBuilder->FindOrCreateAttribute(aNewObj, "AttributePersistentRef");
+      _PTR(AttributePersistentRef) aPRef (anAttr);
+      aPRef->SetValue(thePersistentRef);
+    }
+    if (theComment != "") {
+      anAttr = aStudyBuilder->FindOrCreateAttribute(aNewObj, "AttributeComment");
+      _PTR(AttributeComment) aCmnt (anAttr);
+      aCmnt->SetValue(theComment);
+    }
+    return aNewObj->GetID();
+  }
+
+  //---------------------------------------------------------------
+  struct TResultManager
+  {
+    Result_i* myResult;
+
+    TResultManager(Result_i* theResult):
+      myResult(theResult)
+    {
+      myResult->Register();
+    }
+
+    ~TResultManager()
+    {
+      myResult->Destroy();
+    }
+  };
+
+
+  //---------------------------------------------------------------
+  struct TTransactionManager
+  {
+    _PTR(StudyBuilder) myStudyBuilder;
+
+    TTransactionManager(_PTR(Study) theStudyDocument):
+      myStudyBuilder(theStudyDocument->NewBuilder())
+    {
+      TLock aLock(myMutex);
+      myStudyBuilder->NewCommand();
+    }
+
+    ~TTransactionManager()
+    {
+      TLock aLock(myMutex);
+      myStudyBuilder->CommitCommand();
+    }
+  };
+
+
+  //---------------------------------------------------------------
+  struct TUpdateObjBrowser: public SALOME_Event
+  {
+    int myStudyId;
+    CORBA::Boolean* myIsDone;
+    TUpdateObjBrowser(const int theStudyId,
+                     CORBA::Boolean* theIsDone):
+      myStudyId(theStudyId),
+      myIsDone(theIsDone)
+    {}
+    
+    virtual
+    void
+    Execute()
+    {
+      TLock aLock(myMutex);
+      SUIT_Session* aSession = SUIT_Session::session();
+      QPtrList<SUIT_Application> anApplications = aSession->applications();
+      QPtrListIterator<SUIT_Application> anIter (anApplications);
+      while (SUIT_Application* aSApp = anIter.current()) {
+       if(SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>(aSApp)){
+         if (SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(anApp->activeStudy())) {
+           if (_PTR(Study) aCStudy = aStudy->studyDS()) {
+             if (myStudyId == aCStudy->StudyId()) {
+               TTimerLog aTimerLog(MYTIMEDEBUG,"Result_i::updateObjectBrowser");
+               anApp->updateObjectBrowser();
+               *myIsDone = true;
+               break;
+             }
+           }
+         }
+       }
+       ++anIter;
+      }
+    }
+  };
+
+
+  //---------------------------------------------------------------
+  void
+  BuildEntities(Result_i* theResult,
+               VISU_Convertor* theInput,
+               CORBA::Boolean* theIsDone,
+               std::string theResultEntry,
+               _PTR(Study) theStudy)
+  {
+    if(*theIsDone)
+      return;
+
+    TTimerLog aTimerLog(MYTIMEDEBUG,"Result_i::BuildEntities");
+    TResultManager aResultManager(theResult);
+    TTransactionManager aTransactionManager(theStudy);
+
+    {
+      TTimerLog aTimerLog(MYTIMEDEBUG,"theInput->BuildEntities");
+      theInput->BuildEntities();
+    }
+
+    QString aComment;
+    const TMeshMap& aMeshMap = theInput->GetMeshMap();
+    TMeshMap::const_iterator aMeshMapIter = aMeshMap.begin();
+    for(; aMeshMapIter != aMeshMap.end(); aMeshMapIter++){
+      const string& aMeshName = aMeshMapIter->first;
+      const PMesh& aMesh = aMeshMapIter->second;
+      const TMeshOnEntityMap& aMeshOnEntityMap = aMesh->myMeshOnEntityMap;
+      if(aMeshOnEntityMap.empty()) 
+       continue;
+    
+      aComment.sprintf("myComment=MESH;myName=%s;myDim=%d",
+                      aMeshName.c_str(),
+                      aMesh->myDim);
+      aMesh->myEntry = 
+       CreateAttributes(theStudy,
+                        theResultEntry,
+                        "",
+                        aMeshName,
+                        "",
+                        aComment.latin1(),
+                        true);
+    
+      aComment.sprintf("myComment=FAMILIES;myMeshName=%s",
+                      aMeshName.c_str());
+      string aSubMeshesEntry = 
+       CreateAttributes(theStudy,
+                        aMesh->myEntry,
+                        "",
+                        "Families",
+                        "",
+                        aComment.latin1(),
+                        true);
+      //Import entities
+      TMeshOnEntityMap::const_iterator aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
+      for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++){
+       const TEntity& anEntity = aMeshOnEntityMapIter->first;
+       const PMeshOnEntity& aMeshOnEntity = aMeshOnEntityMapIter->second;
+       
+       string anEntityName;
+       switch(anEntity){
+       case NODE_ENTITY: 
+         anEntityName = "onNodes"; 
+         break;
+       case EDGE_ENTITY: 
+         anEntityName = "onEdges"; 
+         break;
+       case FACE_ENTITY: 
+         anEntityName = "onFaces"; 
+         break;
+       case CELL_ENTITY: 
+         anEntityName = "onCells"; 
+         break;
+       default:
+       continue;
+       }
+       
+       aComment.sprintf("myComment=ENTITY;myType=%d;myMeshName=%s;myId=%d",
+                        VISU::TENTITY,
+                        aMeshName.c_str(),
+                        anEntity);
+       
+       aMeshOnEntity->myEntry = 
+         CreateAttributes(theStudy, 
+                          aSubMeshesEntry, 
+                          "", 
+                          anEntityName.c_str(), 
+                          "", 
+                          aComment.latin1(), 
+                          true);
+      }
+    }
+    
+    ProcessVoidEvent(new TUpdateObjBrowser(theStudy->StudyId(),theIsDone));
+  }
+
+  //---------------------------------------------------------------
+  void
+  BuildGroups(Result_i* theResult,
+             VISU_Convertor* theInput,
+             CORBA::Boolean* theIsDone,
+             CORBA::Boolean theIsBuild,
+             _PTR(Study) theStudy)
+  {
+    if(!theIsBuild || *theIsDone)
+      return;
+
+    TTimerLog aTimerLog(MYTIMEDEBUG,"Result_i::BuildGroups");
+    TResultManager aResultManager(theResult);
+    TTransactionManager aTransactionManager(theStudy);
+    
+    {
+      TTimerLog aTimerLog(MYTIMEDEBUG,"theInput->BuildGroups");
+      theInput->BuildGroups();
+    }
+
+    QString aComment;
+    const TMeshMap& aMeshMap = theInput->GetMeshMap();
+    TMeshMap::const_iterator aMeshMapIter = aMeshMap.begin();
+    for(; aMeshMapIter != aMeshMap.end(); aMeshMapIter++){
+      const string& aMeshName = aMeshMapIter->first;
+      const PMesh& aMesh = aMeshMapIter->second;
+      
+      const TMeshOnEntityMap& aMeshOnEntityMap = aMesh->myMeshOnEntityMap;
+      if(aMeshOnEntityMap.empty()) 
+       continue;
+      
+      TMeshOnEntityMap::const_iterator aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
+      for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++){
+       const TEntity& anEntity = aMeshOnEntityMapIter->first;
+       const PMeshOnEntity& aMeshOnEntity = aMeshOnEntityMapIter->second;
+       
+       const TFamilyMap& aFamilyMap = aMeshOnEntity->myFamilyMap;
+       TFamilyMap::const_iterator aFamilyMapIter = aFamilyMap.begin();
+       for(; aFamilyMapIter != aFamilyMap.end(); aFamilyMapIter++){
+         const string& aFamilyName = aFamilyMapIter->first;
+         const PFamily& aFamily = aFamilyMapIter->second;
+         aComment.sprintf("myComment=FAMILY;myType=%d;myMeshName=%s;myEntityId=%d;myName=%s",
+                          TFAMILY,
+                          aMeshName.c_str(),
+                          anEntity,
+                          aFamilyName.c_str());
+         aFamily->myEntry =
+           CreateAttributes(theStudy,
+                            aMeshOnEntity->myEntry,
+                            "",
+                            aFamilyName,
+                            "",
+                            aComment.latin1(),
+                            true);
+       }
+      }
+      //Importing groups
+      const TGroupMap& aGroupMap = aMesh->myGroupMap;
+      if(!aGroupMap.empty()){
+       aComment.sprintf("myComment=GROUPS;myMeshName=%s",
+                        aMeshName.c_str());
+       string aGroupsEntry =
+         CreateAttributes(theStudy,
+                          aMesh->myEntry,
+                          "",
+                          "Groups",
+                          "",
+                          aComment.latin1(),
+                          true);
+       TGroupMap::const_iterator aGroupMapIter = aGroupMap.begin();
+       for(; aGroupMapIter != aGroupMap.end(); aGroupMapIter++){
+         const string& aGroupName = aGroupMapIter->first;
+         const PGroup& aGroup = aGroupMapIter->second;
+         aComment.sprintf("myComment=GROUP;myType=%d;myMeshName=%s;myName=%s",
+                          TGROUP,aMeshName.c_str(),aGroupName.c_str());
+         aGroup->myEntry = 
+           CreateAttributes(theStudy,
+                            aGroupsEntry,
+                            "",
+                            aGroupName,
+                            "",
+                            aComment.latin1(),
+                            true);
+         const TFamilySet& aFamilySet = aGroup->myFamilySet;
+         TFamilySet::const_iterator aFamilyIter = aFamilySet.begin();
+         for(; aFamilyIter != aFamilySet.end(); aFamilyIter++){
+           const PFamily& aFamily = *aFamilyIter;
+           CreateReference(theStudy,
+                           aGroup->myEntry,
+                           aFamily->myEntry);
+         }
+       }
+      }
+    }
+    
+    ProcessVoidEvent(new TUpdateObjBrowser(theStudy->StudyId(),theIsDone));
+  }
+
+
+  //---------------------------------------------------------------
+  void
+  BuildFields(Result_i* theResult,
+             VISU_Convertor* theInput,
+             CORBA::Boolean* theIsDone,
+             CORBA::Boolean theIsBuild,
+             _PTR(Study) theStudy)
+  {
+    if(!theIsBuild || *theIsDone)
+      return;
+
+    TTimerLog aTimerLog(MYTIMEDEBUG,"Result_i::BuildFields");
+    TResultManager aResultManager(theResult);
+    TTransactionManager aTransactionManager(theStudy);
+
+    {
+      TTimerLog aTimerLog(MYTIMEDEBUG,"theInput->BuildFields");
+      theInput->BuildFields();
+    }
+
+    QString aComment;
+    const TMeshMap& aMeshMap = theInput->GetMeshMap();
+    TMeshMap::const_iterator aMeshMapIter = aMeshMap.begin();
+    for(; aMeshMapIter != aMeshMap.end(); aMeshMapIter++){
+      const string& aMeshName = aMeshMapIter->first;
+      const PMesh& aMesh = aMeshMapIter->second;
+      
+      const TMeshOnEntityMap& aMeshOnEntityMap = aMesh->myMeshOnEntityMap;
+      if(aMeshOnEntityMap.empty()) 
+       continue;
+      
+      //Import fields
+      string aFieldsEntry;
+      bool anIsFieldsEntryCreated = false;
+      
+      TMeshOnEntityMap::const_iterator aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
+      for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++){
+       const TEntity& anEntity = aMeshOnEntityMapIter->first;
+       const PMeshOnEntity& aMeshOnEntity = aMeshOnEntityMapIter->second;
+       const TFieldMap& aFieldMap = aMeshOnEntity->myFieldMap;
+       TFieldMap::const_iterator aFieldMapIter = aFieldMap.begin();
+       for(; aFieldMapIter != aFieldMap.end(); aFieldMapIter++){
+         if(!anIsFieldsEntryCreated){
+           aComment.sprintf("myComment=FIELDS;myMeshName=%s",
+                            aMeshName.c_str());
+           aFieldsEntry =
+             CreateAttributes(theStudy,
+                              aMesh->myEntry,
+                              "",
+                              "Fields",
+                              "",
+                              aComment.latin1(),
+                              true);
+           anIsFieldsEntryCreated = true;
+         }
+         const string& aFieldName = aFieldMapIter->first;
+         const PField& aField = aFieldMapIter->second;
+         const TValField& aValField = aField->myValField;
+         QString aFieldNameWithUnit = GenerateFieldName(aFieldName,aField->myUnitNames[0]);
+         aComment.sprintf("myComment=FIELD;myType=%d;myMeshName=%s;myEntityId=%d;myName=%s;myNbTimeStamps=%d;myNumComponent=%d",
+                          TFIELD,
+                          aMeshName.c_str(),
+                          anEntity,
+                          aFieldName.c_str(),
+                          aValField.size(),
+                          aField->myNbComp);
+         aField->myEntry = 
+           CreateAttributes(theStudy,
+                            aFieldsEntry,
+                            "",
+                            aFieldNameWithUnit.latin1(),
+                            "",
+                            aComment.latin1(),
+                            true);
+         CreateReference(theStudy,
+                         aField->myEntry,
+                         aMeshOnEntity->myEntry);
+         TValField::const_iterator aValFieldIter = aValField.begin();
+         for(; aValFieldIter != aValField.end(); aValFieldIter++){
+           int aTimeStamp = aValFieldIter->first;
+           const PValForTime& aValForTime = aValFieldIter->second;
+           aComment.sprintf("myComment=TIMESTAMP;myType=%d;myMeshName=%s;myEntityId=%d;myFieldName=%s;myTimeStampId=%d;myNumComponent=%d",
+                            TTIMESTAMP,
+                            aMeshName.c_str(),
+                            anEntity,
+                            aFieldName.c_str(),
+                            aTimeStamp,
+                            aField->myNbComp);
+           string aTimeStampId = VISU_Convertor::GenerateName(aValForTime->myTime);
+           aValForTime->myEntry = 
+             CreateAttributes(theStudy,
+                              aField->myEntry,
+                              "",
+                              aTimeStampId,
+                              "",
+                              aComment.latin1(),
+                              true);
+         }
+       }
+      }
+    }
+    
+    ProcessVoidEvent(new TUpdateObjBrowser(theStudy->StudyId(),theIsDone));
+  }
+
+
+  //---------------------------------------------------------------
+  void
+  BuildMinMax(Result_i* theResult,
+             VISU_Convertor* theInput,
+             CORBA::Boolean* theIsDone,
+             CORBA::Boolean theIsBuild,
+             Result_i::TUpdateMinMaxSignal* theUpdateMinMaxSignal)
+  {
+    if(!theIsBuild || *theIsDone)
+      return;
+
+    TTimerLog aTimerLog(MYTIMEDEBUG,"Result_i::BuildMinMax");
+    TResultManager aResultManager(theResult);
+    
+    theInput->BuildMinMax();
+
+    *theIsDone = true;
+
+    (*theUpdateMinMaxSignal)();
+  }
+
+
+  //---------------------------------------------------------------
+  void
+  BuildFieldDataTree(Result_i* theResult,
+                    VISU_Convertor* theInput,
+                    CORBA::Boolean* theIsFieldsDone,
+                    CORBA::Boolean theIsBuildFields,
+                    CORBA::Boolean* theIsMinMaxDone,
+                    CORBA::Boolean theIsBuildMinMax,
+                    Result_i::TUpdateMinMaxSignal* theUpdateMinMaxSignal,
+                    _PTR(Study) theStudy)
+  {
+    BuildFields(theResult,
+               theInput,
+               theIsFieldsDone,
+               theIsBuildFields,
+               theStudy);
+
+    BuildMinMax(theResult,
+               theInput,
+               theIsMinMaxDone,
+               theIsBuildMinMax,
+               theUpdateMinMaxSignal);
+  }
+  
+
+  //---------------------------------------------------------------
+  struct TBuildArgs
+  {
+    Result_i* myResult;
+    VISU_Convertor* myInput;
+    CORBA::Boolean* myIsEntitiesDone;
+    std::string myResultEntry;
+    CORBA::Boolean* myIsFieldsDone;
+    CORBA::Boolean myIsBuildFields;
+    CORBA::Boolean* myIsMinMaxDone;
+    CORBA::Boolean myIsBuildMinMax;
+    Result_i::TUpdateMinMaxSignal* myUpdateMinMaxSignal;
+    CORBA::Boolean* myIsGroupsDone;
+    CORBA::Boolean myIsBuildGroups;
+    _PTR(Study) myStudy;
+
+    TBuildArgs(Result_i* theResult,
+              VISU_Convertor* theInput,
+              CORBA::Boolean* theIsEntitiesDone,
+              std::string theResultEntry,
+              CORBA::Boolean* theIsFieldsDone,
+              CORBA::Boolean theIsBuildFields,
+              CORBA::Boolean* theIsMinMaxDone,
+              CORBA::Boolean theIsBuildMinMax,
+              Result_i::TUpdateMinMaxSignal* theUpdateMinMaxSignal,
+              CORBA::Boolean* theIsGroupsDone,
+              CORBA::Boolean theIsBuildGroups,
+              _PTR(Study) theStudy):
+      myResult(theResult),
+      myInput(theInput),
+      myIsEntitiesDone(theIsEntitiesDone),
+      myResultEntry(theResultEntry),
+      myIsFieldsDone(theIsFieldsDone),
+      myIsBuildFields(theIsBuildFields),
+      myIsMinMaxDone(theIsMinMaxDone),
+      myIsBuildMinMax(theIsBuildMinMax),
+      myUpdateMinMaxSignal(theUpdateMinMaxSignal),
+      myIsGroupsDone(theIsGroupsDone),
+      myIsBuildGroups(theIsBuildGroups),
+      myStudy(theStudy)
+    {}
+      
+  };
+
+  //---------------------------------------------------------------
+  void
+  BuildDataTree(TBuildArgs theBuildArgs)
+  {
+    BuildEntities(theBuildArgs.myResult,
+                 theBuildArgs.myInput,
+                 theBuildArgs.myIsEntitiesDone,
+                 theBuildArgs.myResultEntry,
+                 theBuildArgs.myStudy);
+    {
+      boost::thread aThread(boost::bind(&BuildGroups,
+                                       theBuildArgs.myResult,
+                                       theBuildArgs.myInput,
+                                       theBuildArgs.myIsGroupsDone,
+                                       theBuildArgs.myIsBuildGroups,
+                                       theBuildArgs.myStudy));
+    }
+    {
+      boost::thread aThread(boost::bind(&BuildFieldDataTree,
+                                       theBuildArgs.myResult,
+                                       theBuildArgs.myInput,
+                                       theBuildArgs.myIsFieldsDone,
+                                       theBuildArgs.myIsBuildFields,
+                                       theBuildArgs.myIsMinMaxDone,
+                                       theBuildArgs.myIsBuildMinMax,
+                                       theBuildArgs.myUpdateMinMaxSignal,
+                                       theBuildArgs.myStudy));
+    }
+  }
+  
 }
 
-void CreateReference (SALOMEDS::Study_ptr theStudyDocument,
-                     const string& theFatherEntry, const string& theRefEntry)
+
+//---------------------------------------------------------------
+VISU::MinMaxCunsomer
+::MinMaxCunsomer():
+  myMinMaxIsInitilized(false)
+{}
+
+bool
+VISU::MinMaxCunsomer
+::IsMinMaxInitilized()
 {
-  SALOMEDS::StudyBuilder_var aStudyBuilder = theStudyDocument->NewBuilder();
-  SALOMEDS::SObject_var aFather = theStudyDocument->FindObjectID(theFatherEntry.c_str());
-  SALOMEDS::SObject_var newObj = aStudyBuilder->NewObject(aFather);
-  SALOMEDS::SObject_var aRefSObj = theStudyDocument->FindObjectID(theRefEntry.c_str());
-  aStudyBuilder->Addreference(newObj,aRefSObj);
+  return myMinMaxIsInitilized;
 }
 
-string GetComponentDataType (SALOMEDS::SObject_ptr theSObject)
+void
+VISU::MinMaxCunsomer
+::UpdateMinMax()
 {
-  SALOMEDS::SComponent_var aCompRefSObj = theSObject->GetFatherComponent();
-  CORBA::String_var aDataType = aCompRefSObj->ComponentDataType();
-  return aDataType.in();
+  myMinMaxIsInitilized = true;
 }
 
-//==============================================================================
 
+//---------------------------------------------------------------
 const string VISU::Result_i::myComment = "RESULT";
 const char* VISU::Result_i::GetComment() const { return myComment.c_str();}
 
-VISU::Result_i::Result_i (SALOMEDS::Study_ptr theStudy,
-                         const ESourceId& theSourceId,
-                         const ECreationId& theCreationId):
+//---------------------------------------------------------------
+VISU::Result_i
+::Result_i (SALOMEDS::Study_ptr theStudy,
+           const ESourceId& theSourceId,
+           const ECreationId& theCreationId,
+           CORBA::Boolean theIsBuildImmediately,
+           CORBA::Boolean theIsBuildFields,
+           CORBA::Boolean theIsBuildMinMax,
+           CORBA::Boolean theIsBuildGroups):
   myStudyDocument(SALOMEDS::Study::_duplicate(theStudy)),
   myCreationId(theCreationId),
   mySourceId(theSourceId),
-  myInput(NULL),
-  myIsDone(0)
+  myIsBuildImmediately(theIsBuildImmediately),
+  myIsBuildFields(theIsBuildFields),
+  myIsBuildMinMax(theIsBuildMinMax),
+  myIsBuildGroups(theIsBuildGroups),
+  myIsEntitiesDone(false),
+  myIsFieldsDone(false),
+  myIsGroupsDone(false),
+  myIsMinMaxDone(false),
+  myIsAllDone(false),
+  myInput(NULL)
 {
+  myStudy = ProcessEvent(new TGetStudy(myStudyDocument->StudyId()));
 }
 
 
-void VISU::Result_i::RemoveFromStudy()
+//---------------------------------------------------------------
+void
+VISU::Result_i
+::RemoveFromStudy()
 {
+  struct TRemoveFromStudy: public SALOME_Event
+  {
+    VISU::Result_i* myRemovable;
+    TRemoveFromStudy(VISU::Result_i* theRemovable):
+      myRemovable(theRemovable)
+    {}
+    
+    virtual
+    void
+    Execute()
+    {
+      VISU::RemoveFromStudy(myRemovable->GetSObject(),false);
+      myRemovable->Destroy();
+    }
+  };
+
   // Remove the result with all presentations and other possible sub-objects
-  VISU::RemoveFromStudy(mySObject,false);
+  ProcessVoidEvent(new TRemoveFromStudy(this));
 }
 
 
+//---------------------------------------------------------------
+void 
+VISU::Result_i
+::MinMaxConnect(VISU::MinMaxCunsomer* theMinMaxCunsomer)
+{
+  myUpdateMinMaxSignal.connect(boost::bind(&MinMaxCunsomer::UpdateMinMax,theMinMaxCunsomer));
+}
+
+
+//---------------------------------------------------------------
 int
-VISU::Result_i::
-IsPossible()
+VISU::Result_i
+::IsPossible()
 {
   try{
     float aSize = myInput->GetSize();
@@ -161,13 +863,16 @@ IsPossible()
 }
 
 
+//---------------------------------------------------------------
 CORBA::Boolean
-VISU::Result_i::
-BuildAll()
+VISU::Result_i
+::BuildAll()
 {
-  if(MYDEBUG) MESSAGE("Result_i::Build - myIsDone = "<<myIsDone);
-  if(myIsDone) return 1;
-  if(!IsPossible()) return 0;
+  if(MYDEBUG) MESSAGE("Result_i::Build - myIsAllDone = "<<myIsAllDone);
+  if(myIsAllDone) 
+    return 1;
+  if(!IsPossible()) 
+    return 0;
   try{
     const VISU::TMeshMap& aMeshMap = myInput->GetMeshMap();
     VISU::TMeshMap::const_iterator aMeshMapIter = aMeshMap.begin();
@@ -218,7 +923,7 @@ BuildAll()
        for(; aFamilyMapIter != aFamilyMap.end(); aFamilyMapIter++){
          const string& aFamilyName = aFamilyMapIter->first;
          try{
-           myInput->GetMeshOnEntity(aMeshName,anEntity,aFamilyName);
+           myInput->GetFamilyOnEntity(aMeshName,anEntity,aFamilyName);
          }catch(std::exception& exc){
            INFOS("Follow exception was occured :\n"<<exc.what());
          }catch(...){
@@ -235,195 +940,125 @@ BuildAll()
        }
       }
     }
-    myIsDone = 1;
+    myIsAllDone = 1;
   }catch(std::exception& exc){
     INFOS("Follow exception was occured :\n"<<exc.what());
   }catch(...){
     INFOS("Unknown exception was occured!!!");
   }
-  return myIsDone;
+  return myIsAllDone;
+}
+
+
+//---------------------------------------------------------------
+CORBA::Boolean
+VISU::Result_i
+::Build(CORBA::Boolean theIsBuildAll,
+       CORBA::Boolean theIsAtOnce)
+{
+  if(theIsBuildAll)
+    theIsAtOnce = true;
+
+  if(Build(SALOMEDS::SObject::_nil(),theIsAtOnce)){
+    if(theIsBuildAll)
+      return BuildAll();
+    return true;
+  }
+
+  return false;
 }
 
 
+//---------------------------------------------------------------
 VISU::Storable*
-VISU::Result_i::
-Build(SALOMEDS::SObject_ptr theSObject)
+VISU::Result_i
+::Build(SALOMEDS::SObject_ptr theSObject,
+       CORBA::Boolean theIsAtOnce)
+{
+  if(!myInput)
+    return NULL;
+
+  if(IsDone())
+    return this;
+
+  mySComponent = FindOrCreateVisuComponent(myStudyDocument);
+  CORBA::String_var aSComponentEntry = mySComponent->GetID();
+  CORBA::String_var anIOR(GetID());
+  QString aComment;
+  aComment.sprintf("myComment=%s;myType=%d;myFileName=%s;myInitFileName=%s",
+                  GetComment(),
+                  VISU::TRESULT,
+                  myFileInfo.filePath().latin1(),
+                  myInitFileName.c_str()); // Restoring of Python dump
+  string aResultEntry =
+    CreateAttributes(myStudy,
+                    aSComponentEntry.in(),
+                    anIOR.in(),
+                    myName,
+                    "",
+                    aComment.latin1(),
+                    true);
+  mySObject = myStudyDocument->FindObjectID(aResultEntry.c_str());
+  if(!CORBA::is_nil(theSObject)){
+    CORBA::String_var aString = theSObject->GetID();
+    CreateReference(myStudyDocument,aResultEntry,aString.in());
+  }
+
+  if(theIsAtOnce){
+    BuildEntities(this,
+                 myInput,
+                 &myIsEntitiesDone,
+                 aResultEntry,
+                 myStudy);
+    
+    BuildGroups(this,
+               myInput,
+               &myIsGroupsDone,
+               myIsBuildGroups,
+               myStudy);
+
+    BuildFields(this,
+               myInput,
+               &myIsFieldsDone,
+               myIsBuildFields,
+               myStudy);
+    
+    BuildMinMax(this,
+               myInput,
+               &myIsMinMaxDone,
+               myIsBuildMinMax,
+               &myUpdateMinMaxSignal);
+    
+  }else{
+    TBuildArgs aBuildArgs(this,
+                         myInput,
+                         &myIsEntitiesDone,
+                         aResultEntry,
+                         &myIsFieldsDone,
+                         myIsBuildFields,
+                         &myIsMinMaxDone,
+                         myIsBuildMinMax,
+                         &myUpdateMinMaxSignal,
+                         &myIsGroupsDone,
+                         myIsBuildGroups,
+                         myStudy);
+    boost::thread aThread(boost::bind(&BuildDataTree,
+                                     aBuildArgs));
+  }
+
+  return this;
+}
+
+
+//---------------------------------------------------------------
+VISU::Storable*
+VISU::Result_i
+::BuildAll(SALOMEDS::SObject_ptr theSObject)
 {
-  SALOMEDS::StudyBuilder_var aStudyBuilder = myStudyDocument->NewBuilder();
-  aStudyBuilder->NewCommand();  // There is a transaction
   if(MYDEBUG) MESSAGE("Result_i::Build");
   try{
-    const TMeshMap& aMeshMap = myInput->GetMeshMap();
-    if(aMeshMap.empty())
-      throw std::runtime_error("Build - There is no any mesh information in the file !!!");
-    mySComponent = FindOrCreateVisuComponent(myStudyDocument);
-    CORBA::String_var aSComponentEntry = mySComponent->GetID(), anIOR(GetID());
-    string aRefFatherEntry = GetRefFatherEntry();
-    QString aComment;
-    aComment.sprintf("myComment=%s;myType=%d;myFileName=%s;myInitFileName=%s",
-                    GetComment(),
-                    VISU::TRESULT,
-                    myFileInfo.filePath().latin1(),
-                    myInitFileName.c_str()); // Restoring of Python dump
-    string aResultEntry =
-      CreateAttributes(myStudyDocument,
-                      aSComponentEntry,
-                      aRefFatherEntry.c_str(),
-                      anIOR,
-                      myName.c_str(),
-                      "",
-                      aComment.latin1(),
-                      true);
-    mySObject = myStudyDocument->FindObjectID(aResultEntry.c_str());
-    if(mySObject->_is_nil()) throw std::runtime_error("Build - There is no SObject for the Result !!!");
-    if(!CORBA::is_nil(theSObject)){
-      CORBA::String_var aString = theSObject->GetID();
-      CreateReference(myStudyDocument,aResultEntry,aString.in());
-    }
-    TMeshMap::const_iterator aMeshMapIter = aMeshMap.begin();
-    for(; aMeshMapIter != aMeshMap.end(); aMeshMapIter++){
-      const string& aMeshName = aMeshMapIter->first;
-      const VISU::PMesh aMesh = aMeshMapIter->second;
-      const VISU::TMeshOnEntityMap& aMeshOnEntityMap = aMesh->myMeshOnEntityMap;
-      VISU::TMeshOnEntityMap::const_iterator aMeshOnEntityMapIter;
-      aComment.sprintf("myComment=MESH;myName=%s;myDim=%d",
-                      aMeshName.c_str(),aMesh->myDim);
-      string aMeshEntry = CreateAttributes(myStudyDocument,aResultEntry.c_str(),aRefFatherEntry.c_str(),
-                                          "",aMeshName.c_str(),"",aComment.latin1(),true);
-      if(aMeshOnEntityMap.empty()) continue;
-      aComment.sprintf("myComment=FAMILIES;myMeshName=%s",aMeshName.c_str());
-      string aSubMeshesEntry = CreateAttributes(myStudyDocument,aMeshEntry.c_str(),aRefFatherEntry.c_str(),
-                                               "","Families","",aComment.latin1(),true);
-      //Import entities and according families
-      aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
-      typedef std::map<std::string,std::string> TComment2EntryMap;
-      TComment2EntryMap aComment2EntryMap;
-      typedef std::map<VISU::TEntity,std::string> TEntity2EntryMap;
-      TEntity2EntryMap aEntity2EntryMap;
-      for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++){
-       const VISU::TEntity& anEntity = aMeshOnEntityMapIter->first;
-       aComment.sprintf("myComment=ENTITY;myType=%d;myMeshName=%s;myId=%d",
-                        VISU::TENTITY,
-                        aMeshName.c_str(),
-                        anEntity);
-       string anEntityName;
-       switch(anEntity){
-       case VISU::NODE_ENTITY : anEntityName = "onNodes"; break;
-       case VISU::EDGE_ENTITY : anEntityName = "onEdges"; break;
-       case VISU::FACE_ENTITY : anEntityName = "onFaces"; break;
-       case VISU::CELL_ENTITY : anEntityName = "onCells"; break;
-       default:
-         throw std::runtime_error("Build >> Value of entity is incorrect!");
-       }
-       aEntity2EntryMap[anEntity] = CreateAttributes
-         (myStudyDocument, aSubMeshesEntry.c_str(), aRefFatherEntry.c_str(),
-          "", anEntityName.c_str(), "", aComment.latin1(), true);
-       const VISU::PMeshOnEntity aMeshOnEntity = aMeshOnEntityMapIter->second;
-       const VISU::TFamilyMap& aFamilyMap = aMeshOnEntity->myFamilyMap;
-       VISU::TFamilyMap::const_iterator aFamilyMapIter = aFamilyMap.begin();
-       for(; aFamilyMapIter != aFamilyMap.end(); aFamilyMapIter++){
-         const string& aFamilyName = aFamilyMapIter->first;
-         aComment.sprintf("myComment=FAMILY;myType=%d;myMeshName=%s;myEntityId=%d;myName=%s",
-                          VISU::TFAMILY,
-                          aMeshName.c_str(),
-                          anEntity,
-                          aFamilyName.c_str());
-         aComment2EntryMap[aComment.latin1()] =
-           CreateAttributes(myStudyDocument,
-                            aEntity2EntryMap[anEntity].c_str(),
-                            aRefFatherEntry.c_str(),
-                            "",
-                            aFamilyName.c_str(),
-                            "",
-                            aComment.latin1(),
-                            true);
-       }
-      }
-      //Importing groups
-      const VISU::TGroupMap& aGroupMap = aMesh->myGroupMap;
-      if(aGroupMap.size() > 0){
-       aComment.sprintf("myComment=GROUPS;myMeshName=%s",
-                        aMeshName.c_str());
-       string aGroupsEntry =
-         CreateAttributes(myStudyDocument,
-                          aMeshEntry.c_str(),
-                          aRefFatherEntry.c_str(),
-                          "",
-                          "Groups",
-                          "",
-                          aComment.latin1(),
-                          true);
-       VISU::TGroupMap::const_iterator aGroupMapIter = aGroupMap.begin();
-       for(; aGroupMapIter != aGroupMap.end(); aGroupMapIter++){
-         const string& aGroupName = aGroupMapIter->first;
-         aComment.sprintf("myComment=GROUP;myType=%d;myMeshName=%s;myName=%s",
-                          VISU::TGROUP,aMeshName.c_str(),aGroupName.c_str());
-         string aGroupEntry = CreateAttributes(myStudyDocument,aGroupsEntry.c_str(),aRefFatherEntry.c_str(),
-                                               "",aGroupName.c_str(),"",aComment.latin1(),true);
-         const VISU::PGroup aGroup = aGroupMapIter->second;
-         const VISU::TFamilyAndEntitySet& aFamilyAndEntitySet = aGroup->myFamilyAndEntitySet;
-         VISU::TFamilyAndEntitySet::const_iterator aFamilyAndEntitySetIter = aFamilyAndEntitySet.begin();
-         for(; aFamilyAndEntitySetIter != aFamilyAndEntitySet.end(); aFamilyAndEntitySetIter++){
-           const VISU::TFamilyAndEntity& aFamilyAndEntity = *aFamilyAndEntitySetIter;
-           const string& aFamilyName = aFamilyAndEntity.first;
-           const VISU::TEntity& anEntity = aFamilyAndEntity.second;
-           aComment.sprintf("myComment=FAMILY;myType=%d;myMeshName=%s;myEntityId=%d;myName=%s",
-                            VISU::TFAMILY,
-                            aMeshName.c_str(),
-                            anEntity,
-                            aFamilyName.c_str());
-           CreateReference(myStudyDocument,aGroupEntry,aComment2EntryMap[aComment.latin1()]);
-         }
-       }
-      }
-      //Import fields
-      string aFieldsEntry;
-      bool isFieldEntryCreated = 0;
-      aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
-      for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++){
-       const VISU::TEntity& anEntity = aMeshOnEntityMapIter->first;
-       const VISU::PMeshOnEntity aMeshOnEntity = aMeshOnEntityMapIter->second;
-       const VISU::TFieldMap& aFieldMap = aMeshOnEntity->myFieldMap;
-       VISU::TFieldMap::const_iterator aFieldMapIter = aFieldMap.begin();
-       for(; aFieldMapIter != aFieldMap.end(); aFieldMapIter++){
-         if(!isFieldEntryCreated){
-           aComment.sprintf("myComment=FIELDS;myMeshName=%s",
-                            aMeshName.c_str());
-           aFieldsEntry =
-             CreateAttributes(myStudyDocument,
-                              aMeshEntry.c_str(),
-                              aRefFatherEntry.c_str(),
-                              "",
-                              "Fields",
-                              "",
-                              aComment.latin1(),
-                              true);
-           isFieldEntryCreated = true;
-         }
-         const string& aFieldName = aFieldMapIter->first;
-         const VISU::PField aField = aFieldMapIter->second;
-         const VISU::TValField& aValField = aField->myValField;
-         QString aFieldNameWithUnit = ::GenerateFieldName(aFieldName,aField->myUnitNames[0]);
-         aComment.sprintf("myComment=FIELD;myType=%d;myMeshName=%s;myEntityId=%d;myName=%s;myNbTimeStamps=%d;myNumComponent=%d",
-                          VISU::TFIELD,aMeshName.c_str(),anEntity,aFieldName.c_str(),aValField.size(),aField->myNbComp);
-         string aFieldEntry = CreateAttributes(myStudyDocument,aFieldsEntry.c_str(),aRefFatherEntry.c_str(),
-                                               "",aFieldNameWithUnit.latin1(),"",aComment.latin1(),true);
-         CreateReference(myStudyDocument,aFieldEntry,aEntity2EntryMap[anEntity]);
-         VISU::TValField::const_iterator aValFieldIter = aValField.begin();
-         for(; aValFieldIter != aValField.end(); aValFieldIter++){
-           int aTimeStamp = aValFieldIter->first;
-           const VISU::PValForTime aValForTime = aValFieldIter->second;
-           aComment.sprintf("myComment=TIMESTAMP;myType=%d;myMeshName=%s;myEntityId=%d;myFieldName=%s;myTimeStampId=%d;myNumComponent=%d",
-                            VISU::TTIMESTAMP,aMeshName.c_str(),anEntity,aFieldName.c_str(),aTimeStamp,aField->myNbComp);
-           string aTimeStampId = VISU_Convertor::GenerateName(aValForTime->myTime);
-           CreateAttributes(myStudyDocument,aFieldEntry.c_str(),aRefFatherEntry.c_str(),
-                            "",aTimeStampId.c_str(),"",aComment.latin1(),true);
-         }
-       }
-      }
-    }
-    bool isBuildAll = VISU::GetResourceMgr()->booleanValue("VISU", "full_med_loading", false);
-    if(isBuildAll) BuildAll();
+    Build(theSObject);
+    BuildAll();
   }catch(std::exception& exc){
     INFOS("Follow exception was occured :\n"<<exc.what());
     return NULL;
@@ -431,11 +1066,12 @@ Build(SALOMEDS::SObject_ptr theSObject)
     INFOS("Unknown exception was occured!!!");
     return NULL;
   }
-  aStudyBuilder->CommitCommand();
+
   return this;
 }
 
 
+//---------------------------------------------------------------
 VISU::Storable*
 VISU::Result_i::
 Create(const char* theFileName)
@@ -456,9 +1092,11 @@ Create(const char* theFileName)
       myFileInfo.setFile(QString(aTmpDir.c_str()) + myFileInfo.fileName());
     }
     myInput = CreateConvertor(myFileInfo.absFilePath().latin1());
-    if(!myInput)
-      throw std::runtime_error("Create - Cannot create a Convertor for this file!!!");
-    return Build();
+    if(myInput){
+      if(myIsBuildImmediately)
+       Build(SALOMEDS::SObject::_nil());
+      return this;
+    }
   }catch(std::exception& exc){
     INFOS("Follow exception was occured :\n"<<exc.what());
   }catch(...){
@@ -468,6 +1106,7 @@ Create(const char* theFileName)
 }
 
 
+//---------------------------------------------------------------
 VISU::Storable*
 VISU::Result_i::
 Create(SALOMEDS::SObject_ptr theMedSObject)
@@ -478,14 +1117,15 @@ Create(SALOMEDS::SObject_ptr theMedSObject)
     if(myInput == NULL)
       return NULL;
 
+    myInput->Build();
+
     string aCompDataType = GetComponentDataType(theMedSObject);
     myFileInfo.setFile(aCompDataType.c_str());
     myInitFileName = aCompDataType;
 
     myName = ::GenerateName("aResult").latin1();
 
-    VISU::Storable* aStorable = Build(theMedSObject);
-    return aStorable;
+    return Build(theMedSObject);
   }catch(std::exception& exc){
     INFOS("Follow exception was occured :\n"<<exc.what());
   }catch(...){
@@ -494,6 +1134,8 @@ Create(SALOMEDS::SObject_ptr theMedSObject)
   return NULL;
 }
 
+
+//---------------------------------------------------------------
 VISU::Storable*
 VISU::Result_i::
 Create(SALOME_MED::FIELD_ptr theField)
@@ -504,6 +1146,8 @@ Create(SALOME_MED::FIELD_ptr theField)
     if(myInput == NULL)
       return NULL;
 
+    myInput->Build();
+
     string aCompDataType = "MED";
     myFileInfo.setFile(aCompDataType.c_str());
     myInitFileName = aCompDataType;
@@ -513,8 +1157,7 @@ Create(SALOME_MED::FIELD_ptr theField)
     CORBA::String_var anIOR = myStudyDocument->ConvertObjectToIOR(theField);
     SALOMEDS::SObject_var aFieldSObject = myStudyDocument->FindObjectIOR(anIOR);
 
-    VISU::Storable* aStorable = Build(aFieldSObject);
-    return aStorable;
+    return Build(aFieldSObject);
   }catch(std::exception& exc){
     INFOS("Follow exception was occured :\n"<<exc.what());
   }catch(...){
@@ -524,6 +1167,7 @@ Create(SALOME_MED::FIELD_ptr theField)
 }
 
 
+//---------------------------------------------------------------
 VISU::Storable*
 VISU::Result_i::
 Restore(SALOMEDS::SObject_ptr theSObject,
@@ -540,7 +1184,8 @@ Restore(SALOMEDS::SObject_ptr theSObject,
 
     SALOMEDS::SObject_var aRefSObj, aTargetRefSObj;
     if (mySObject->FindSubObject(1, aRefSObj) &&
-       aRefSObj->ReferencedObject(aTargetRefSObj)) {
+       aRefSObj->ReferencedObject(aTargetRefSObj)) 
+    {
       if(MYDEBUG) MESSAGE("Result_i::GetInput - There is some reference.");
       SALOMEDS::SComponent_var aCompRefSObj = aTargetRefSObj->GetFatherComponent();
       CORBA::String_var aDataType = aCompRefSObj->ComponentDataType();
@@ -553,9 +1198,16 @@ Restore(SALOMEDS::SObject_ptr theSObject,
       SALOMEDS::StudyBuilder_var aStudyBuilder = myStudyDocument->NewBuilder();
       SALOMEDS::Driver_var aDriver = SALOMEDS::Driver::_narrow(aEngComp);
       aStudyBuilder->LoadWith(aCompRefSObj, aDriver);
-      if (strcmp(aDataType, "MED") == 0)
-       myInput = CreateMEDConvertor(aTargetRefSObj);
-      else
+      if (strcmp(aDataType, "MED") == 0){
+        // create field or MED converter
+        CORBA::Object_var aMedObject = VISU::SObjectToObject(aTargetRefSObj);
+        SALOME_MED::FIELD_var aField = SALOME_MED::FIELD::_narrow(aMedObject);
+        if(!CORBA::is_nil(aField))
+          myInput = CreateMEDFieldConvertor(aField);
+        else
+          myInput = CreateMEDConvertor(aTargetRefSObj);
+       myInput->Build();
+      }else
        throw std::runtime_error("GetInput - There is no convertor for the aDataType !!!");
     } else {
       myFileInfo.setFile(thePrefix.c_str());
@@ -610,6 +1262,21 @@ Restore(SALOMEDS::SObject_ptr theSObject,
       }
       if(MYDEBUG) MESSAGE("VISU::Result_i::Restore - mySourceId = " << mySourceId);
       myInput = CreateConvertor(myFileInfo.filePath().latin1());
+
+      myInput->BuildEntities();
+      if(myIsBuildFields){
+       myInput->BuildFields();
+       myIsFieldsDone = true;
+       if(myIsBuildMinMax){
+         myInput->BuildMinMax();
+         myIsMinMaxDone = true;
+       }
+      }
+      if(myIsBuildGroups){
+       myInput->BuildGroups();
+       myIsGroupsDone = true;
+      }
+
       QString aComment;
       aComment.sprintf("myComment=%s;myType=%d;myFileName=%s;myInitFileName=%s",
                       GetComment(), VISU::TRESULT, myFileInfo.filePath().latin1(),
@@ -620,8 +1287,8 @@ Restore(SALOMEDS::SObject_ptr theSObject,
       SALOMEDS::AttributeComment_var aCmnt = SALOMEDS::AttributeComment::_narrow(anAttr);
       aCmnt->SetValue(aComment.latin1());
     }
-    bool isBuildAll = VISU::GetResourceMgr()->booleanValue("VISU", "full_med_loading", false);
-    if (isBuildAll)
+    bool anIsBuildAll = VISU::GetResourceMgr()->booleanValue("VISU", "full_med_loading", false);
+    if(anIsBuildAll)
       BuildAll();
     return this;
   } catch(std::exception& exc) {
@@ -632,21 +1299,94 @@ Restore(SALOMEDS::SObject_ptr theSObject,
   return NULL;
 }
 
-VISU::Result_i::TInput* VISU::Result_i::GetInput() {
+//---------------------------------------------------------------
+VISU::Result_i::TInput* 
+VISU::Result_i
+::GetInput() 
+{
   return myInput;
 }
 
-void VISU::Result_i::ToStream(std::ostringstream& theStr){
+//---------------------------------------------------------------
+CORBA::Boolean 
+VISU::Result_i
+::IsDone() 
+{
+  return 
+    myIsEntitiesDone && 
+    (myIsBuildFields? myIsFieldsDone: true) &&
+    (myIsBuildMinMax? myIsMinMaxDone: true) &&
+    (myIsBuildGroups? myIsGroupsDone: true);
+}
+
+CORBA::Boolean 
+VISU::Result_i
+::IsEntitiesDone() 
+{
+  return myIsEntitiesDone;
+}
+
+void
+VISU::Result_i
+::SetBuildFields(CORBA::Boolean theIsBuildFields, 
+                CORBA::Boolean theIsCalculateMinMax)
+{
+  myIsBuildFields = theIsBuildFields;
+  if(theIsBuildFields)
+    myIsBuildMinMax = theIsCalculateMinMax;
+  else
+    myIsBuildMinMax = false;
+}
+
+void
+VISU::Result_i
+::SetBuildGroups(CORBA::Boolean theIsBuildGroups)
+{
+  myIsBuildGroups = theIsBuildGroups;
+}
+
+CORBA::Boolean 
+VISU::Result_i
+::IsFieldsDone() 
+{
+  return myIsFieldsDone;
+}
+
+CORBA::Boolean 
+VISU::Result_i
+::IsGroupsDone() 
+{
+  return myIsGroupsDone;
+}
+
+CORBA::Boolean 
+VISU::Result_i
+::IsMinMaxDone() 
+{
+  return myIsMinMaxDone;
+}
+
+//---------------------------------------------------------------
+void 
+VISU::Result_i
+::ToStream(std::ostringstream& theStr)
+{
   if(MYDEBUG) MESSAGE(GetComment());
   Storable::DataToStream(theStr,"myName",myName.c_str());
   Storable::DataToStream(theStr,"myInitFileName",myInitFileName.c_str());
   Storable::DataToStream(theStr,"myCreationId",myCreationId);
+  Storable::DataToStream(theStr,"myIsBuildFields",myIsFieldsDone);
+  Storable::DataToStream(theStr,"myIsBuildMinMax",myIsMinMaxDone);
+  Storable::DataToStream(theStr,"myIsBuildGroups",myIsGroupsDone);
 }
 
+
+//---------------------------------------------------------------
 VISU::Storable*
-VISU::Result_i::Restore(SALOMEDS::SObject_ptr theSObject,
-                       const string& thePrefix,
-                       const Storable::TRestoringMap& theMap)
+VISU::Result_i
+::Restore(SALOMEDS::SObject_ptr theSObject,
+         const string& thePrefix,
+         const Storable::TRestoringMap& theMap)
 {
   SALOMEDS::Study_var aStudy = theSObject->GetStudy();
 
@@ -655,32 +1395,71 @@ VISU::Result_i::Restore(SALOMEDS::SObject_ptr theSObject,
   if(aCreationId == eImportMed || aCreationId == eImportMedField)
     aSourceId = eRestoredComponent;
 
-  VISU::Result_i* pResult = new VISU::Result_i(aStudy,aSourceId,aCreationId);
-  if (pResult == NULL)
+  CORBA::Boolean anIsBuildFields = Storable::FindValue(theMap,"myIsBuildFields","0").toInt();
+  CORBA::Boolean anIsBuildMinMax = Storable::FindValue(theMap,"myIsBuildMinMax","0").toInt();
+  CORBA::Boolean anIsBuildGroups = Storable::FindValue(theMap,"myIsBuildGroups","0").toInt();
+
+  VISU::Result_i* aResult = new VISU::Result_i(aStudy,
+                                              aSourceId,
+                                              aCreationId,
+                                              anIsBuildFields,
+                                              anIsBuildMinMax,
+                                              anIsBuildGroups);
+  if (aResult == NULL)
     return NULL;
 
-  return pResult->Restore(theSObject,theMap,thePrefix);
+  return aResult->Restore(theSObject,theMap,thePrefix);
 }
 
-string VISU::Result_i::GetRefFatherEntry() {
-  //return QAD_Application::getDesktop()->getActiveStudy()->getActiveStudyFrame()->entry();
+
+//---------------------------------------------------------------
+string 
+VISU::Result_i
+::GetRefFatherEntry() 
+{
   return "";
 }
 
-string VISU::Result_i::GetEntry(){
+string
+VISU::Result_i
+::GetEntry()
+{
   CORBA::String_var anEntry = mySObject->GetID();
   return string(anEntry);
 }
 
-const SALOMEDS::SObject_var& VISU::Result_i::GetSObject() const { return mySObject;}
-const SALOMEDS::Study_var& VISU::Result_i::GetStudyDocument() const { return myStudyDocument;}
-const SALOMEDS::SComponent_var& VISU::Result_i::GetSComponent() const { return mySComponent;}
-std::string VISU::Result_i::GetEntry(const std::string& theComment)
+const SALOMEDS::SObject_var& 
+VISU::Result_i
+::GetSObject() const 
+{ 
+  return mySObject;
+}
+
+const SALOMEDS::Study_var& 
+VISU::Result_i
+::GetStudyDocument() const 
+{ 
+  return myStudyDocument;
+}
+
+const SALOMEDS::SComponent_var& 
+VISU::Result_i
+::GetSComponent() const
+{
+  return mySComponent;
+}
+
+std::string 
+VISU::Result_i
+::GetEntry(const std::string& theComment)
 {
   return FindEntryWithComment(myStudyDocument,GetEntry().c_str(),theComment.c_str());
 }
 
-VISU::Result_i::~Result_i()
+
+//---------------------------------------------------------------
+VISU::Result_i
+::~Result_i()
 {
   MESSAGE("Result_i::~Result_i() - this = "<<this);
   if (mySourceId == eRestoredFile) {
@@ -724,9 +1503,12 @@ const vector< float >* Result_i::GetAxisInfo(const string& theMeshName,
       MESSAGE("No mesh named " << theMeshName );
       return components;
     }
-    VISU_Convertor::TOutput* vtkMesh = myInput->GetMeshOnEntity (theMeshName,
-                                                                 CELL_ENTITY);
-    if ( !vtkMesh || vtkMesh->GetNumberOfCells() == 0 ) {
+
+    VISU::PIDMapper anIDMapper = myInput->GetMeshOnEntity(theMeshName,
+                                                         CELL_ENTITY);
+    VISU::TVTKOutput* aMesh = anIDMapper->GetVTKOutput();
+
+    if ( !aMesh || aMesh->GetNumberOfCells() == 0 ) {
       MESSAGE( "No cells in the mesh: " << theMeshName );
       return components;
     }
@@ -737,9 +1519,9 @@ const vector< float >* Result_i::GetAxisInfo(const string& theMeshName,
     gp_Vec axDirs[ nbAxes ];
     float minSize[3] = { FLT_MAX, FLT_MAX, FLT_MAX };
     bool axesComputed = false;
-    for ( vtkIdType iCell = 0; iCell < vtkMesh->GetNumberOfCells(); ++iCell )
+    for ( vtkIdType iCell = 0; iCell < aMesh->GetNumberOfCells(); ++iCell )
     {
-      vtkCell* cell = vtkMesh->GetCell( iCell );
+      vtkCell* cell = aMesh->GetCell( iCell );
       int nbPnt = cell->GetNumberOfPoints();
       if ( nbPnt != 8 )
         continue;
@@ -787,8 +1569,8 @@ const vector< float >* Result_i::GetAxisInfo(const string& theMeshName,
     // on axis direction; define bnd box
     set< float > comps[ 3 ];
     Bnd_Box box;
-    vtkPoints * points = vtkMesh->GetPoints();
-    vtkIdType iP, nbP = vtkMesh->GetNumberOfPoints();
+    vtkPoints * points = aMesh->GetPoints();
+    vtkIdType iP, nbP = aMesh->GetNumberOfPoints();
     for ( iP = 0; iP < nbP; ++iP )
     {
       float* coo = points->GetPoint( iP );