Salome HOME
0021799: EDF 2344 SMESH: Existing groups are not taken into account when adding new...
[modules/smesh.git] / src / SMESHGUI / SMESHGUI.cxx
index 6ab62a0afa4247bac43d4b15f6c0494b403b32a4..52f3180adab914968c21c6acefd7b3f7ff9e247f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -76,6 +76,7 @@
 #include "SMESHGUI_TransparencyDlg.h"
 #include "SMESHGUI_DuplicateNodesDlg.h"
 #include "SMESHGUI_CopyMeshDlg.h"
+#include "SMESHGUI_ReorientFacesDlg.h"
 
 #include "SMESHGUI_Utils.h"
 #include "SMESHGUI_MeshUtils.h"
 #include <SalomeApp_Study.h>
 #include <SalomeApp_Application.h>
 #include <SalomeApp_CheckFileDlg.h>
+#include <SalomeApp_DataObject.h>
 
 #include <LightApp_DataOwner.h>
 #include <LightApp_Preferences.h>
 
 // Qt includes
 // #define       INCLUDE_MENUITEM_DEF // VSR commented ????????
+#include <QApplication>
 #include <QMenu>
 #include <QTextStream>
 
         }
       }
     }
+    
+    // Warn the user about presence of not supported elements
+    QString format;
+    std::vector< SMESH::EntityType > notSupportedElemTypes, presentNotSupported;
+    if ( isDAT )
+    {
+      format = "DAT";
+      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Quadrangle );
+      notSupportedElemTypes.push_back( SMESH::Entity_BiQuad_Quadrangle );
+      notSupportedElemTypes.push_back( SMESH::Entity_Polygon );
+      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polygon );
+      notSupportedElemTypes.push_back( SMESH::Entity_Tetra );
+      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Tetra );
+      notSupportedElemTypes.push_back( SMESH::Entity_Pyramid );
+      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Pyramid );
+      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Hexa );
+      notSupportedElemTypes.push_back( SMESH::Entity_TriQuad_Hexa );
+      notSupportedElemTypes.push_back( SMESH::Entity_Penta );
+      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Penta );
+      notSupportedElemTypes.push_back( SMESH::Entity_Hexagonal_Prism );
+      notSupportedElemTypes.push_back( SMESH::Entity_Polyhedra );
+      notSupportedElemTypes.push_back( SMESH::Entity_0D );
+      notSupportedElemTypes.push_back( SMESH::Entity_Ball );
+    }
     else if ( isUNV )
     {
-      // warn the user about presence of not supported elements
+      format = "UNV";
+      notSupportedElemTypes.push_back( SMESH::Entity_Polygon );
+      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polygon );
+      notSupportedElemTypes.push_back( SMESH::Entity_Polyhedra );
+      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polyhedra );
+      notSupportedElemTypes.push_back( SMESH::Entity_Pyramid );
+      notSupportedElemTypes.push_back( SMESH::Entity_Hexagonal_Prism );
+      notSupportedElemTypes.push_back( SMESH::Entity_0D );
+      notSupportedElemTypes.push_back( SMESH::Entity_Ball );
+    }
+    else if ( isSTL )
+    {
+      format = "STL";
+      notSupportedElemTypes.push_back( SMESH::Entity_Edge );
+      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Edge );
+      notSupportedElemTypes.push_back( SMESH::Entity_0D );
+      notSupportedElemTypes.push_back( SMESH::Entity_Ball );
+    }
+    else if ( isCGNS )
+    {
+      format = "CGNS";
+      notSupportedElemTypes.push_back( SMESH::Entity_Ball );
+    }
+    else if ( isSAUV )
+    {
+      format = "SAUV";
+      notSupportedElemTypes.push_back( SMESH::Entity_Ball );
+      notSupportedElemTypes.push_back( SMESH::Entity_BiQuad_Quadrangle );
+      notSupportedElemTypes.push_back( SMESH::Entity_TriQuad_Hexa );
+      notSupportedElemTypes.push_back( SMESH::Entity_Hexagonal_Prism );
+      notSupportedElemTypes.push_back( SMESH::Entity_Polygon );
+      notSupportedElemTypes.push_back( SMESH::Entity_Polyhedra );
+    }
+    if ( ! notSupportedElemTypes.empty() )
+    {
       SMESH::long_array_var nbElems = aMeshOrGroup->GetMeshInfo();
-      int nbNotSupported = ( nbElems[ SMESH::Entity_Pyramid ] +
-                             nbElems[ SMESH::Entity_Quad_Pyramid ] +
-                             nbElems[ SMESH::Entity_Hexagonal_Prism ] +
-                             nbElems[ SMESH::Entity_Polygon ] +
-                             nbElems[ SMESH::Entity_Polyhedra ] );
-      if ( nbNotSupported > 0 ) {
-        int aRet = SUIT_MessageBox::warning
-          (SMESHGUI::desktop(),
-           QObject::tr("SMESH_WRN_WARNING"),
-           QObject::tr("SMESH_EXPORT_UNV").arg(aMeshName),
-           QObject::tr("SMESH_BUT_YES"),
-           QObject::tr("SMESH_BUT_NO"), 0, 1);
-        if (aRet != 0)
-          return;
+      for ( size_t iType = 0; iType < notSupportedElemTypes.size(); ++iType )
+        if ( nbElems[ notSupportedElemTypes[ iType ]] > 0 )
+          presentNotSupported.push_back( notSupportedElemTypes[ iType ]);
+    }
+    if ( !presentNotSupported.empty() )
+    {
+      QString typeNames;
+      const char* typeMsg[SMESH::Entity_Last] = { "SMESH_NODES",
+        "SMESH_ELEMS0D","SMESH_EDGES","SMESH_QUADRATIC_EDGES","SMESH_TRIANGLES",
+        "SMESH_QUADRATIC_TRIANGLES","SMESH_QUADRANGLES","SMESH_QUADRATIC_QUADRANGLES",
+        "SMESH_BIQUADRATIC_QUADRANGLES","SMESH_POLYGONS","SMESH_QUADRATIC_POLYGONS",
+        "SMESH_TETRAHEDRA","SMESH_QUADRATIC_TETRAHEDRONS","SMESH_PYRAMIDS",
+        "SMESH_QUADRATIC_PYRAMIDS","SMESH_HEXAHEDRA","SMESH_QUADRATIC_HEXAHEDRONS",
+        "SMESH_TRIQUADRATIC_HEXAHEDRONS","SMESH_PENTAHEDRA","SMESH_QUADRATIC_PENTAHEDRONS",
+        "SMESH_OCTAHEDRA","SMESH_POLYEDRONS","SMESH_QUADRATIC_POLYEDRONS","SMESH_BALLS"
+      };
+      QString andStr = " " + QObject::tr("SMESH_AND") + " ", comma(", ");
+      for ( size_t iType = 0; iType < presentNotSupported.size(); ++iType ) {
+        typeNames += QObject::tr( typeMsg[ presentNotSupported[ iType ]]);
+        if ( iType != presentNotSupported.size() - 1 )
+          typeNames += ( iType == presentNotSupported.size() - 2 ) ? andStr : comma;
       }
+      int aRet = SUIT_MessageBox::warning
+        (SMESHGUI::desktop(),
+         QObject::tr("SMESH_WRN_WARNING"),
+         QObject::tr("EXPORT_NOT_SUPPORTED").arg(aMeshName).arg(format).arg(typeNames),
+         QObject::tr("SMESH_BUT_YES"),
+         QObject::tr("SMESH_BUT_NO"), 0, 1);
+      if (aRet != 0)
+        return;
     }
 
     // Get parameters of export operation
 //         bool Renumber = false;
 //         // PAL 14172  : Check of we have to renumber or not from the preferences before export
 //         if (resMgr)
-//           Renumber= resMgr->booleanValue("SMESH","renumbering");
+//           Renumber= resMgr->booleanValue("renumbering");
 //         if (Renumber){
 //           SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
 //           aMeshEditor->RenumberNodes();
           if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){
             unsigned int aMode = anActor->GetEntityMode();
             switch(theCommandID){
+            case 222:
+              InverseEntityMode(aMode,SMESH_Actor::eBallElem);
+              break;
             case 216:
               InverseEntityMode(aMode,SMESH_Actor::e0DElements);
               break;
       _PTR(SObject) aGroupSObject = SMESH::FindSObject(aGroupObject);
       if (aGroupSObject) {
         if(SMESH_Actor *anActor = SMESH::FindActorByEntry(aGroupSObject->GetID().c_str())) {
-          if( aGroupObject->GetType() == SMESH::NODE )
-            anActor->SetNodeColor( aColor.R, aColor.G, aColor.B );
-          else if( aGroupObject->GetType() == SMESH::EDGE )
-            anActor->SetEdgeColor( aColor.R, aColor.G, aColor.B );
-          else if( aGroupObject->GetType() == SMESH::ELEM0D )
-            anActor->Set0DColor( aColor.R, aColor.G, aColor.B );
-          else {
+          switch ( aGroupObject->GetType ()) {
+          case SMESH::NODE:
+            anActor->SetNodeColor( aColor.R, aColor.G, aColor.B ); break;
+          case SMESH::EDGE:
+            anActor->SetEdgeColor( aColor.R, aColor.G, aColor.B ); break;
+          case SMESH::ELEM0D:
+            anActor->Set0DColor( aColor.R, aColor.G, aColor.B ); break;
+          case SMESH::BALL:
+            anActor->SetBallColor( aColor.R, aColor.G, aColor.B ); break;
+          default:
             QColor c;
             int delta;
             SMESH::GetColor("SMESH", "fill_color", c, delta, "0,170,255|-100");
     }
   }
 
-  void SetDisplayMode(int theCommandID, SMESHGUI_StudyId2MarkerMap& theMarkerMap){
+  void SetDisplayMode(int theCommandID, SMESHGUI_StudyId2MarkerMap& theMarkerMap)
+  {
     SALOME_ListIO selected;
     SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
     if( !app )
         return;
       }
       case 1132:{
-        QColor c, e, b, n, c0D, o, outl, selection, preselection;
+        QColor c, e, b, n, c0D, cBall, o, outl, selection, preselection;
         int delta;
-        int size0D = 0;
+        int size0D = 0, ballSize = 0;
         int Edgewidth = 0;
         vtkFloatingPointType Shrink = 0.0;
         vtkFloatingPointType faces_orientation_scale = 0.0;
               c2 = int (color0D[2] * 255);
               c0D.setRgb(c0, c1, c2);
 
+              vtkFloatingPointType ballcolor[3];
+              anActor->GetBallColor(ballcolor[0], ballcolor[1], ballcolor[2]);
+              c0 = int (ballcolor[0] * 255);
+              c1 = int (ballcolor[1] * 255);
+              c2 = int (ballcolor[2] * 255);
+              cBall.setRgb(c0, c1, c2);
+
               vtkFloatingPointType outlineColor[3];
               anActor->GetOutlineColor(outlineColor[0], outlineColor[1], outlineColor[2]);
               c0 = int (outlineColor[0] * 255);
               size0D = (int)anActor->Get0DSize();
               if(size0D == 0)
                 size0D = 1;
+              ballSize = (int)anActor->GetBallSize();
+              if(ballSize == 0)
+                ballSize = 1;
               Edgewidth = (int)anActor->GetLineWidth();
               if(Edgewidth == 0)
                 Edgewidth = 1;
 
         SMESHGUI_Preferences_ColorDlg *aDlg =
           new SMESHGUI_Preferences_ColorDlg( SMESHGUI::GetSMESHGUI() );
+        aDlg->SetBooleanValue(1, faces_orientation_3dvectors);
         aDlg->SetColor(1, c);
         aDlg->SetColor(2, e);
         aDlg->SetColor(3, n);
         aDlg->SetColor(4, outl);
-        aDlg->SetDeltaBrightness(delta);
         aDlg->SetColor(5, c0D);
-        aDlg->SetColor(6, o);
+        aDlg->SetColor(6, cBall);
+        aDlg->SetColor(7, o);
+        aDlg->SetColor(8, selection);
+        aDlg->SetColor(9, preselection);
+        aDlg->SetDeltaBrightness(delta);
+        aDlg->SetDoubleValue(1, faces_orientation_scale);
         aDlg->SetIntValue(1, Edgewidth);
         aDlg->SetIntValue(2, int(Shrink*100.));
         aDlg->SetIntValue(3, size0D);
-        aDlg->SetDoubleValue(1, faces_orientation_scale);
-        aDlg->SetBooleanValue(1, faces_orientation_3dvectors);
-        aDlg->SetColor(7, selection);
-        aDlg->SetColor(8, preselection);
+        aDlg->SetIntValue(4, ballSize);
  
         aDlg->setCustomMarkerMap( theMarkerMap[ aStudy->StudyId() ] );
 
           aDlg->setCustomMarker( aMarkerTextureCurrent );
 
         if(aDlg->exec()){
-          QColor color = aDlg->GetColor(1);
-          QColor edgecolor = aDlg->GetColor(2);
-          QColor nodecolor = aDlg->GetColor(3);
-          QColor outlinecolor = aDlg->GetColor(4);
-          QColor color0D = aDlg->GetColor(5);
-          QColor faces_orientation_color = aDlg->GetColor(6);
-          QColor selectioncolor = aDlg->GetColor(7);
-          QColor preSelectioncolor = aDlg->GetColor(8);
+          QColor color                   = aDlg->GetColor(1);
+          QColor edgecolor               = aDlg->GetColor(2);
+          QColor nodecolor               = aDlg->GetColor(3);
+          QColor outlinecolor            = aDlg->GetColor(4);
+          QColor color0D                 = aDlg->GetColor(5);
+          QColor ballcolor               = aDlg->GetColor(6);
+          QColor faces_orientation_color = aDlg->GetColor(7);
+          QColor selectioncolor          = aDlg->GetColor(8);
+          QColor preSelectioncolor       = aDlg->GetColor(9);
           int delta = aDlg->GetDeltaBrightness();
 
           /* Point marker */
                                     vtkFloatingPointType (color0D.blue()) / 255.);
                 anActor->Set0DSize(aDlg->GetIntValue(3));
 
+                /* Ball elements */
+                anActor->SetBallColor(vtkFloatingPointType (ballcolor.red()) / 255.,
+                                      vtkFloatingPointType (ballcolor.green()) / 255.,
+                                      vtkFloatingPointType (ballcolor.blue()) / 255.);
+                anActor->SetBallSize(aDlg->GetIntValue(4));
+
                 /* Faces orientation */
                 vtkFloatingPointType c[3] = {vtkFloatingPointType(faces_orientation_color.redF()),
                                              vtkFloatingPointType(faces_orientation_color.greenF()),
 
     SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
 
-      SALOME_ListIteratorOfListIO It(selected);
-      
-      aStudyBuilder->NewCommand();  // There is a transaction
-      for( ; It.More(); It.Next()){ // loop on selected IO's
-        Handle(SALOME_InteractiveObject) IObject = It.Value();
-        if(IObject->hasEntry()) {
-          _PTR(SObject) aSO = aStudy->FindObjectID(IObject->getEntry());
-          
-          // disable removal of "SMESH" component object
-          if(aSO->FindAttribute(anAttr, "AttributeIOR")){
-            anIOR = anAttr;
-            if ( engineIOR() == anIOR->Value().c_str() )
-              continue;
-          }
-          //Check the referenced object
-          _PTR(SObject) aRefSObject;
-          if ( aSO && aSO->ReferencedObject( aRefSObject ) )
-            aSO = aRefSObject; // Delete main Object instead of reference
-          
-          // put the whole hierarchy of sub-objects of the selected SO into a list and
-          // then treat them all starting from the deepest objects (at list back)
-          
-          std::list< _PTR(SObject) > listSO;
-          listSO.push_back( aSO );
-          std::list< _PTR(SObject) >::iterator itSO = listSO.begin();
-          for ( ; itSO != listSO.end(); ++itSO ) {
-            _PTR(ChildIterator) it = aStudy->NewChildIterator( *itSO );
-            for (it->InitEx(false); it->More(); it->Next())
-              listSO.push_back( it->Value() );
-          }
-          
-          // treat SO's in the list starting from the back
-          
-          std::list< _PTR(SObject) >::reverse_iterator ritSO = listSO.rbegin();
-          for ( ; ritSO != listSO.rend(); ++ritSO ) {
-            _PTR(SObject) SO = *ritSO;
-            if ( !SO ) continue;
-            std::string anEntry = SO->GetID();
-            
-            /** Erase graphical object **/
-          if(SO->FindAttribute(anAttr, "AttributeIOR")){
-            ViewManagerList aViewMenegers = anApp->viewManagers();
-            ViewManagerList::const_iterator it = aViewMenegers.begin();
-            for( ; it != aViewMenegers.end(); it++) {         
-              SUIT_ViewManager* vm = *it;
-              int nbSf = vm ? vm->getViewsCount() : 0;
-              if(vm) {
-                QVector<SUIT_ViewWindow*> aViews = vm->getViews();
-                for(int i = 0; i < nbSf; i++){
-                  SUIT_ViewWindow *sf = aViews[i];
-                  if(SMESH_Actor* anActor = SMESH::FindActorByEntry(sf,anEntry.c_str())){
-                    SMESH::RemoveActor(sf,anActor);
-                  }
-                }
+    // Put the whole hierarchy of sub-objects of the selected SO's into a list and
+    // then treat them all starting from the deepest objects (at list back)
+    std::list< _PTR(SObject) > listSO;
+    SALOME_ListIteratorOfListIO It(selected);
+    for( ; It.More(); It.Next()) // loop on selected IO's
+    {
+      Handle(SALOME_InteractiveObject) IObject = It.Value();
+      if(IObject->hasEntry()) {
+        _PTR(SObject) aSO = aStudy->FindObjectID(IObject->getEntry());
+
+        // disable removal of "SMESH" component object
+        if(aSO->FindAttribute(anAttr, "AttributeIOR")){
+          anIOR = anAttr;
+          if ( engineIOR() == anIOR->Value().c_str() )
+            continue;
+        }
+        //Check the referenced object
+        _PTR(SObject) aRefSObject;
+        if ( aSO && aSO->ReferencedObject( aRefSObject ) )
+          aSO = aRefSObject; // Delete main Object instead of reference
+
+        listSO.push_back( aSO );
+        std::list< _PTR(SObject) >::iterator itSO = listSO.begin();
+        for ( ; itSO != listSO.end(); ++itSO ) {
+          _PTR(ChildIterator) it = aStudy->NewChildIterator( *itSO );
+          for (it->InitEx(false); it->More(); it->Next())
+            listSO.push_back( it->Value() );
+        }
+      }
+    }
+    // Check if none of objects to delete is referred from outside
+    std::list< _PTR(SObject) >::reverse_iterator ritSO;
+    for ( ritSO = listSO.rbegin(); ritSO != listSO.rend(); ++ritSO )
+    {
+      _PTR(SObject) SO = *ritSO;
+      if ( !SO ) continue;
+      std::vector<_PTR(SObject)> aReferences = aStudy->FindDependances( *ritSO  );
+      for (size_t i = 0; i < aReferences.size(); i++) {
+        _PTR(SComponent) aComponent = aReferences[i]->GetFatherComponent();
+        std::string type = aComponent->ComponentDataType();
+        if ( type != "SMESH" )
+        {
+          SUIT_MessageBox::warning( anApp->desktop(),
+                                    QObject::tr("WRN_WARNING"),
+                                    QObject::tr("DEP_OBJECT") );
+          return; // outside SMESH, there is an object depending on a SMESH object 
+        }
+      }
+    }
+
+    // Treat SO's in the list starting from the back
+    aStudyBuilder->NewCommand();  // There is a transaction
+    for ( ritSO = listSO.rbegin(); ritSO != listSO.rend(); ++ritSO )
+    {
+      _PTR(SObject) SO = *ritSO;
+      if ( !SO ) continue;
+      std::string anEntry = SO->GetID();
+
+      /** Erase graphical object **/
+      if(SO->FindAttribute(anAttr, "AttributeIOR")){
+        ViewManagerList aViewMenegers = anApp->viewManagers();
+        ViewManagerList::const_iterator it = aViewMenegers.begin();
+        for( ; it != aViewMenegers.end(); it++) {         
+          SUIT_ViewManager* vm = *it;
+          int nbSf = vm ? vm->getViewsCount() : 0;
+          if(vm) {
+            QVector<SUIT_ViewWindow*> aViews = vm->getViews();
+            for(int i = 0; i < nbSf; i++){
+              SUIT_ViewWindow *sf = aViews[i];
+              if(SMESH_Actor* anActor = SMESH::FindActorByEntry(sf,anEntry.c_str())){
+                SMESH::RemoveActor(sf,anActor);
               }
             }
           }
-            /** Remove an object from data structures **/
-            SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( SMESH::SObjectToObject( SO ));
-            SMESH::SMESH_subMesh_var   aSubMesh = SMESH::SMESH_subMesh::_narrow( SMESH::SObjectToObject( SO ));
-            if ( !aGroup->_is_nil() ) {                          // DELETE GROUP
-              SMESH::SMESH_Mesh_var aMesh = aGroup->GetMesh();
-              aMesh->RemoveGroup( aGroup );
-            }
-            else if ( !aSubMesh->_is_nil() ) {                   // DELETE SUBMESH
-              SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
-              aMesh->RemoveSubMesh( aSubMesh );
-              
-              _PTR(SObject) aMeshSO = SMESH::FindSObject(aMesh);
-              if (aMeshSO)
-                SMESH::ModifiedMesh(aMeshSO, false, aMesh->NbNodes()==0);
-            }
-            else {
-              IObject = new SALOME_InteractiveObject
-                ( anEntry.c_str(), engineIOR().toLatin1().data(), SO->GetName().c_str() );
-              QString objType = CheckTypeObject(IObject);
-              if ( objType == "Hypothesis" || objType == "Algorithm" ) {// DELETE HYPOTHESIS
-                SMESH::RemoveHypothesisOrAlgorithmOnMesh(IObject);
-                aStudyBuilder->RemoveObjectWithChildren( SO );
-              }
-              else {// default action: remove SObject from the study
-                // san - it's no use opening a transaction here until UNDO/REDO is provided in SMESH
-                //SUIT_Operation *op = new SALOMEGUI_ImportOperation(myActiveStudy);
-                //op->start();
-                aStudyBuilder->RemoveObjectWithChildren( SO );
-                //op->finish();
-              }
-            }
-          } /* listSO back loop */
-        } /* IObject->hasEntry() */
-      } /* more/next */
-    
+        }
+      }
+      /** Remove an object from data structures **/
+      SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( SMESH::SObjectToObject( SO ));
+      SMESH::SMESH_subMesh_var   aSubMesh = SMESH::SMESH_subMesh::_narrow( SMESH::SObjectToObject( SO ));
+      if ( !aGroup->_is_nil() ) {                          // DELETE GROUP
+        SMESH::SMESH_Mesh_var aMesh = aGroup->GetMesh();
+        aMesh->RemoveGroup( aGroup );
+      }
+      else if ( !aSubMesh->_is_nil() ) {                   // DELETE SUBMESH
+        SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
+        aMesh->RemoveSubMesh( aSubMesh );
+
+        _PTR(SObject) aMeshSO = SMESH::FindSObject(aMesh);
+        if (aMeshSO)
+          SMESH::ModifiedMesh(aMeshSO, false, aMesh->NbNodes()==0);
+      }
+      else {
+        Handle(SALOME_InteractiveObject) IObject = new SALOME_InteractiveObject
+          ( anEntry.c_str(), engineIOR().toLatin1().data(), SO->GetName().c_str() );
+        QString objType = CheckTypeObject(IObject);
+        if ( objType == "Hypothesis" || objType == "Algorithm" ) {// DELETE HYPOTHESIS
+          SMESH::RemoveHypothesisOrAlgorithmOnMesh(IObject);
+          aStudyBuilder->RemoveObjectWithChildren( SO );
+        }
+        else {// default action: remove SObject from the study
+              // san - it's no use opening a transaction here until UNDO/REDO is provided in SMESH
+              //SUIT_Operation *op = new SALOMEGUI_ImportOperation(myActiveStudy);
+              //op->start();
+          aStudyBuilder->RemoveObjectWithChildren( SO );
+          //op->finish();
+        }
+      }
+    } /* listSO back loop */
+
     aStudyBuilder->CommitCommand();
 
     /* Clear any previous selection */
 
     SMESHGUI::GetSMESHGUI()->updateObjBrowser();
   }
-//}
+//} namespace
 
 extern "C" {
   SMESHGUI_EXPORT CAM_Module* createModule()
@@ -1713,11 +1832,14 @@ LightApp_Module( "SMESH" )
     myComponentSMESH->SetBoundaryBoxSegmentation( nbSeg );
     nbSeg = aResourceMgr->integerValue( "SMESH", "nb_segments_per_edge", 15 );
     myComponentSMESH->SetDefaultNbSegments( nbSeg );
-    if ( aResourceMgr->hasValue( "SMESH", "historical_python_dump" ))
-    {
-      QString val = aResourceMgr->stringValue( "SMESH", "historical_python_dump" );
-      myComponentSMESH->SetOption( "historical_python_dump", val.toLatin1().constData() );
-    }
+
+    const char* options[] = { "historical_python_dump", "forget_mesh_on_hyp_modif" };
+    for ( size_t i = 0; i < sizeof(options)/sizeof(char*); ++i )
+      if ( aResourceMgr->hasValue( "SMESH", options[i] ))
+      {
+        QString val = aResourceMgr->stringValue( "SMESH", options[i] );
+        myComponentSMESH->SetOption( options[i], val.toLatin1().constData() );
+      }
   }
 
   myActiveDialogBox = 0;
@@ -2142,7 +2264,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
 
   case 1134: // Clipping
   case 1133: // Tranparency
-  case 1132: // Colors / Size
+  case 1132: // Display preferences (colors, shrink size, line width, ...)
 
     // Display Mode
   case 215: // Nodes
@@ -2164,6 +2286,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case 218: // Faces
   case 219: // Volumes
   case 220: // All Entity
+  case 222: // Balls
     ::SetDisplayEntity(theCommandID);
   break;
 
@@ -2305,16 +2428,10 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     break;
   }
 
-  case 701:                                     // COMPUTE MESH
-  case 711:                                     // PRECOMPUTE MESH
-  case 712:                                     // EVALUATE MESH
-  case 713:                                     // MESH ORDER
-    {
-      if (checkLock(aStudy)) break;
-      startOperation( theCommandID );
-    }
-    break;
-
+  case 701: // COMPUTE MESH
+  case 711: // PRECOMPUTE MESH
+  case 712: // EVALUATE MESH
+  case 713: // MESH ORDER
   case 702: // Create mesh
   case 703: // Create sub-mesh
   case 704: // Edit mesh/sub-mesh
@@ -2459,26 +2576,11 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       break;
     }
   case 417: // Convert mesh to quadratic
-    {
-    startOperation( 417 );
-      /*      if (checkLock(aStudy)) break;
-      if (vtkwnd) {
-        EmitSignalDeactivateDialog();
-        new SMESHGUI_ConvToQuadDlg();
-      } else {
-        SUIT_MessageBox::warning(desktop(),
-                               tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
-                               }*/
-      break;
-    }
   case 418: // create 2D mesh from 3D
+  case 420: // Reorient faces
+  case 806: // CREATE GEO GROUP
     {
-      startOperation( 418 );
-      break;
-    }
-  case 806:                                     // CREATE GEO GROUP
-    {
-      startOperation( 806 );
+      startOperation( theCommandID );
       break;
     }
   case 801:                                     // CREATE GROUP
@@ -2828,6 +2930,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       break;
     }
 
+  case 4008:                                    // BALL
   case 4009:                                    // ELEM0D
   case 4010:                                    // EDGE
   case 4021:                                    // TRIANGLE
@@ -2844,24 +2947,16 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
         EmitSignalDeactivateDialog();
         SMDSAbs_EntityType type = SMDSEntity_Edge;
         switch (theCommandID) {
-        case 4009:
-          type = SMDSEntity_0D; break;
-        case 4021:
-          type = SMDSEntity_Triangle; break;
-        case 4022:
-          type = SMDSEntity_Quadrangle; break;
-        case 4031:
-          type = SMDSEntity_Tetra; break;
-        case 4023:
-          type = SMDSEntity_Polygon; break;
-        case 4032:
-          type = SMDSEntity_Hexa; break;
-        case 4133:
-          type = SMDSEntity_Penta; break;
-        case 4134:
-          type = SMDSEntity_Pyramid; break;
-        case 4135:
-          type = SMDSEntity_Hexagonal_Prism; break;
+        case 4008: type = SMDSEntity_Ball;            break;
+        case 4009: type = SMDSEntity_0D;              break;
+        case 4021: type = SMDSEntity_Triangle;        break;
+        case 4022: type = SMDSEntity_Quadrangle;      break;
+        case 4031: type = SMDSEntity_Tetra;           break;
+        case 4023: type = SMDSEntity_Polygon;         break;
+        case 4032: type = SMDSEntity_Hexa;            break;
+        case 4133: type = SMDSEntity_Penta;           break;
+        case 4134: type = SMDSEntity_Pyramid;         break;
+        case 4135: type = SMDSEntity_Hexagonal_Prism; break;
         default:;
         }
         ( new SMESHGUI_AddMeshElementDlg( this, type ) )->show();
@@ -3414,13 +3509,13 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   // ----- create actions --------------
 
-  createSMESHAction(  111, "DAT", "", (Qt::CTRL+Qt::Key_B) );
-  createSMESHAction(  112, "UNV", "", (Qt::CTRL+Qt::Key_U) );
-  createSMESHAction(  113, "MED", "", (Qt::CTRL+Qt::Key_M) );
+  createSMESHAction(  111, "IMPORT_DAT", "", (Qt::CTRL+Qt::Key_B) );
+  createSMESHAction(  112, "IMPORT_UNV", "", (Qt::CTRL+Qt::Key_U) );
+  createSMESHAction(  113, "IMPORT_MED", "", (Qt::CTRL+Qt::Key_M) );
   createSMESHAction(  114, "NUM" );
-  createSMESHAction(  115, "STL" );
-  createSMESHAction(  116, "CGNS" );
-  createSMESHAction(  117, "SAUV" );
+  createSMESHAction(  115, "IMPORT_STL" );
+  createSMESHAction(  116, "IMPORT_CGNS" );
+  createSMESHAction(  117, "IMPORT_SAUV" );
   createSMESHAction(  121, "DAT" );
   createSMESHAction(  122, "MED" );
   createSMESHAction(  123, "UNV" );
@@ -3489,6 +3584,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( 6009, "VOLUME_3D",       "ICON_VOLUME_3D",     0, true );
   createSMESHAction( 4000, "NODE",            "ICON_DLG_NODE" );
   createSMESHAction( 4009, "ELEM0D",          "ICON_DLG_ELEM0D" );
+  createSMESHAction( 4008, "BALL",            "ICON_DLG_BALL" );
   createSMESHAction( 4010, "EDGE",            "ICON_DLG_EDGE" );
   createSMESHAction( 4021, "TRIANGLE",        "ICON_DLG_TRIANGLE" );
   createSMESHAction( 4022, "QUAD",            "ICON_DLG_QUADRANGLE" );
@@ -3536,6 +3632,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction(  417, "CONV_TO_QUAD",    "ICON_CONV_TO_QUAD" );
   createSMESHAction(  418, "2D_FROM_3D",      "ICON_2D_FROM_3D" );
   createSMESHAction(  419, "SPLIT_TO_TETRA",  "ICON_SPLIT_TO_TETRA" );
+  createSMESHAction(  420, "REORIENT_2D",     "ICON_REORIENT_2D" );
   createSMESHAction(  200, "RESET" );
   createSMESHAction(  201, "SCALAR_BAR_PROP" );
   createSMESHAction(  2021, "SAVE_DISTRIBUTION" );
@@ -3548,6 +3645,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction(  213, "SHRINK",         "ICON_SHRINK", 0, true );
   createSMESHAction(  214, "UPDATE",         "ICON_UPDATE" );
   createSMESHAction(  215, "NODES",          "ICON_POINTS", 0, true );
+  createSMESHAction(  222, "BALLS",          "ICON_DLG_BALL", 0, true );
   createSMESHAction(  216, "ELEMS0D",        "ICON_DLG_ELEM0D", 0, true );
   createSMESHAction(  217, "EDGES",          "ICON_DLG_EDGE", 0, true );
   createSMESHAction(  218, "FACES",          "ICON_DLG_TRIANGLE", 0, true );
@@ -3574,8 +3672,8 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( 501, "MEASURE_MIN_DIST", "ICON_MEASURE_MIN_DIST" );
   createSMESHAction( 502, "MEASURE_BND_BOX",  "ICON_MEASURE_BND_BOX" );
 
-  createSMESHAction( 300, "ERASE" );
-  createSMESHAction( 301, "DISPLAY" );
+  createSMESHAction( 300, "HIDE" );
+  createSMESHAction( 301, "SHOW" );
   createSMESHAction( 302, "DISPLAY_ONLY" );
 
   // ----- create menu --------------
@@ -3681,6 +3779,7 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   createMenu( 4000, addId, -1 );
   createMenu( 4009, addId, -1 );
+  createMenu( 4008, addId, -1 );
   createMenu( 4010, addId, -1 );
   createMenu( 4021, addId, -1 );
   createMenu( 4022, addId, -1 );
@@ -3726,6 +3825,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( 407, modifyId, -1 );
   createMenu( 408, modifyId, -1 );
   createMenu( 409, modifyId, -1 );
+  createMenu( 420, modifyId, -1 );
   createMenu( 410, modifyId, -1 );
   createMenu( 411, modifyId, -1 );
   createMenu( 419, modifyId, -1 );
@@ -3804,6 +3904,7 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   createTool( 4000, addRemTb );
   createTool( 4009, addRemTb );
+  createTool( 4008, addRemTb );
   createTool( 4010, addRemTb );
   createTool( 4021, addRemTb );
   createTool( 4022, addRemTb );
@@ -3847,6 +3948,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createTool( 407, modifyTb );
   createTool( 408, modifyTb );
   createTool( 409, modifyTb );
+  createTool( 420, modifyTb );
   createTool( 410, modifyTb );
   createTool( 411, modifyTb );
   createTool( 419, modifyTb );
@@ -3893,6 +3995,7 @@ void SMESHGUI::initialize( CAM_Application* app )
     hasNodes("(numberOfNodes > 0 )"),//&& isVisible)"),
     hasElems("(count( elemTypes ) > 0)"),
     hasDifferentElems("(count( elemTypes ) > 1)"),
+    hasBalls("({'BallElem'} in elemTypes)"),
     hasElems0d("({'Elem0d'} in elemTypes)"),
     hasEdges("({'Edge'} in elemTypes)"),
     hasFaces("({'Face'} in elemTypes)"),
@@ -3940,6 +4043,7 @@ void SMESHGUI::initialize( CAM_Application* app )
 #endif
   createPopupItem( 145, OB, mesh_group, multiple_non_empty );   // EXPORT_SAUV
   createPopupItem(  33, OB, mesh_part + " " + hyp_alg );        // DELETE
+  createPopupItem( 813, OB, group );                            // DEL_GROUP with contents
   popupMgr()->insert( separator(), -1, 0 );
 
   // popup for viewer
@@ -4028,6 +4132,10 @@ void SMESHGUI::initialize( CAM_Application* app )
   popupMgr()->setRule( action( 219 ), aDiffElemsInVTK + "&& isVisible &&" + hasVolumes, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 219 ), "{'Volume'} in entityMode", QtxPopupMgr::ToggleRule );
 
+  popupMgr()->insert( action( 222 ), anId, -1 ); // BALLS
+  popupMgr()->setRule( action( 222 ), aDiffElemsInVTK + "&& isVisible &&" + hasBalls, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 222 ), "{'BallElem'} in entityMode", QtxPopupMgr::ToggleRule );
+
   popupMgr()->insert( separator(), anId, -1 );
 
   popupMgr()->insert( action( 220 ), anId, -1 ); // ALL
@@ -4579,6 +4687,11 @@ void SMESHGUI::createPreferences()
   setPreferenceProperty( nbSeg, "min", 1 );
   setPreferenceProperty( nbSeg, "max", 10000000 );
 
+  int loadGroup = addPreference( tr( "SMESH_PREF_MESH_LOADING" ), genTab );
+  addPreference( tr( "PREF_FORGET_MESH_AT_HYP_MODIF" ), loadGroup, LightApp_Preferences::Bool,
+                 "SMESH", "forget_mesh_on_hyp_modif" );
+
+
   // Quantities with individual precision settings
   int precGroup = addPreference( tr( "SMESH_PREF_GROUP_PRECISION" ), genTab );
   setPreferenceProperty( precGroup, "columns", 2 );
@@ -4652,7 +4765,7 @@ void SMESHGUI::createPreferences()
 
   int ColorId = addPreference( tr( "PREF_FILL"     ), elemGroup, LightApp_Preferences::BiColor, "SMESH", "fill_color" );
   addPreference( tr( "PREF_COLOR_0D" ), elemGroup, LightApp_Preferences::Color, "SMESH", "elem0d_color" );
-
+  addPreference( tr( "PREF_BALL_COLOR" ), elemGroup, LightApp_Preferences::Color, "SMESH", "ball_elem_color" );
   addPreference( tr( "PREF_OUTLINE"  ), elemGroup, LightApp_Preferences::Color, "SMESH", "outline_color" );
   addPreference( tr( "PREF_WIREFRAME"  ), elemGroup, LightApp_Preferences::Color, "SMESH", "wireframe_color" );
 
@@ -4665,6 +4778,8 @@ void SMESHGUI::createPreferences()
 
   int size0d = addPreference(tr("PREF_SIZE_0D"), elemGroup,
                              LightApp_Preferences::IntSpin, "SMESH", "elem0d_size");
+  int ballSize = addPreference(tr("PREF_BALL_SIZE"), elemGroup,
+                             LightApp_Preferences::IntSpin, "SMESH", "ball_elem_size");
   int elemW  = addPreference(tr("PREF_WIDTH"), elemGroup,
                              LightApp_Preferences::IntSpin, "SMESH", "element_width");
   int shrink = addPreference(tr("PREF_SHRINK_COEFF"), elemGroup,
@@ -4673,6 +4788,9 @@ void SMESHGUI::createPreferences()
   setPreferenceProperty( size0d, "min", 1 );
   setPreferenceProperty( size0d, "max", 10 );
 
+  setPreferenceProperty( ballSize, "min", 1 );
+  setPreferenceProperty( ballSize, "max", 10 );
+
   setPreferenceProperty( elemW, "min", 1 );
   setPreferenceProperty( elemW, "max", 5 );
 
@@ -4860,9 +4978,10 @@ void SMESHGUI::preferencesChanged( const QString& sect, const QString& name )
       int nbSeg = aResourceMgr->integerValue( "SMESH", "nb_segments_per_edge", 15 );
       myComponentSMESH->SetDefaultNbSegments( nbSeg );
     }
-    else if ( name == "historical_python_dump" ) {
-      QString val = aResourceMgr->stringValue( "SMESH", "historical_python_dump" );
-      myComponentSMESH->SetOption( "historical_python_dump", val.toLatin1().constData() );
+    else if ( name == "historical_python_dump" ||
+              name == "forget_mesh_on_hyp_modif") {
+      QString val = aResourceMgr->stringValue( "SMESH", name );
+      myComponentSMESH->SetOption( name.toLatin1().constData(), val.toLatin1().constData() );
     }
 
     if(aWarning.size() != 0){
@@ -4943,6 +5062,9 @@ LightApp_Operation* SMESHGUI::createOperation( const int id ) const
     case 418: // create 2D mesh as boundary on 3D
       op = new SMESHGUI_Make2DFrom3DOp();
     break;
+    case 420: // Reorient faces
+      op = new SMESHGUI_ReorientFacesOp();
+      break;
     case 701: // Compute mesh
       op = new SMESHGUI_ComputeOp();
     break;
@@ -5936,6 +6058,35 @@ void SMESHGUI::onViewClosed( SUIT_ViewWindow* pview ) {
 #endif
 }
 
+void SMESHGUI::message( const QString& msg )
+{
+  // dispatch message
+  QStringList data = msg.split("/");
+  if ( data.count() > 0 ) {
+    if ( data.first() == "mesh_loading" ) {
+      // get mesh entry
+      QString entry = data.count() > 1 ? data[1] : QString();
+      if ( entry.isEmpty() )
+        return;
+      // get study
+      _PTR(Study) study = dynamic_cast<SalomeApp_Study*>( application()->activeStudy() )->studyDS();
+      // get mesh name
+      _PTR(SObject) obj = study->FindObjectID( entry.toLatin1().constData() );
+      QString name;
+      if ( obj )
+        name = obj->GetName().c_str();
+      if ( name.isEmpty() )
+        return;
+      
+      if ( data.last() == "stop" )
+        application()->putInfo( tr( "MESH_LOADING_MSG_FINISHED" ).arg( name ) );
+      else
+        application()->putInfo( tr( "MESH_LOADING_MSG" ).arg( name ) );
+      QApplication::processEvents();
+    }
+  }
+}
+
 /*!
   \brief Connects or disconnects signals about activating and cloning view on the module slots
   \param pview view which is connected/disconnected
@@ -5962,16 +6113,20 @@ bool SMESHGUI::renameAllowed( const QString& entry) const {
   if( !anApp )
     return false;
 
-  _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); //Document OCAF de l'etude active
-  if( !aStudy )
+  SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
+  if( !appStudy )
+    return false;
+
+  SalomeApp_DataObject* obj = dynamic_cast<SalomeApp_DataObject*>(appStudy->findObjectByEntry(entry));
+  
+  if(!obj)
     return false;
 
-  bool appRes = SalomeApp_Module::renameAllowed(entry);
-  if( !appRes )
+  if(appStudy->isComponent(entry) || obj->isReference())
     return false;
 
   // check type to prevent renaming of inappropriate objects
-  int aType = SMESHGUI_Selection::type(qPrintable(entry), aStudy);
+  int aType = SMESHGUI_Selection::type(qPrintable(entry), SMESH::GetActiveStudyDocument());
   if (aType == MESH || aType == GROUP ||
       aType == SUBMESH || aType == SUBMESH_COMPOUND ||
       aType == SUBMESH_SOLID || aType == SUBMESH_FACE ||
@@ -5993,14 +6148,23 @@ bool SMESHGUI::renameObject( const QString& entry, const QString& name) {
   SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( application() );
   if( !anApp )
     return false;
+    
+  SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
 
-  _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); //Document OCAF de l'etude active
-  if( !aStudy )
+  if(!appStudy)
     return false;
-
-  bool appRes = SalomeApp_Module::renameObject(entry,name);
-  if( !appRes )
+  
+  _PTR(Study) aStudy = appStudy->studyDS();
+  
+  if(!aStudy)
     return false;
+  
+  bool aLocked = (_PTR(AttributeStudyProperties)(appStudy->studyDS()->GetProperties()))->IsLocked();
+  if ( aLocked ) {
+    SUIT_MessageBox::warning ( anApp->desktop(), QObject::tr("WRN_WARNING"), QObject::tr("WRN_STUDY_LOCKED") );
+    return false;
+  }
+
 
   _PTR(SObject) obj = aStudy->FindObjectID( qPrintable(entry) );
   _PTR(GenericAttribute) anAttr;
@@ -6009,7 +6173,7 @@ bool SMESHGUI::renameObject( const QString& entry, const QString& name) {
     if ( obj->FindAttribute(anAttr, "AttributeName") ) {
       aName = anAttr;
       // check type to prevent renaming of inappropriate objects
-      int aType = SMESHGUI_Selection::type( qPrintable(entry), aStudy );
+      int aType = SMESHGUI_Selection::type( qPrintable(entry), SMESH::GetActiveStudyDocument() );
       if (aType == MESH || aType == GROUP ||
           aType == SUBMESH || aType == SUBMESH_COMPOUND ||
           aType == SUBMESH_SOLID || aType == SUBMESH_FACE ||