Salome HOME
Update in accordance with changes in QtxComboBox.
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_ComputeDlg.cxx
index edb1f7dbaaab0627e2fbe2c2b00da5507826cca5..8627f72fcd7d0f0604cc2ee5569bf299f8e2795b 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 //
 #include "SMESHGUI_ComputeDlg.h"
 
+#include "SMDS_Mesh.hxx"
+#include "SMDS_SetIterator.hxx"
 #include "SMESHGUI.h"
 #include "SMESHGUI_GEOMGenUtils.h"
-#include "SMESHGUI_MeshUtils.h"
-#include "SMESHGUI_VTKUtils.h"
-#include "SMESHGUI_MeshInfosBox.h"
 #include "SMESHGUI_HypothesesUtils.h"
 #include "SMESHGUI_MeshEditPreview.h"
-#include "SMESHGUI_MeshOrderOp.h"
+#include "SMESHGUI_MeshInfosBox.h"
 #include "SMESHGUI_MeshOrderDlg.h"
-
+#include "SMESHGUI_MeshOrderOp.h"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_VTKUtils.h"
 #include "SMESH_Actor.h"
 #include "SMESH_ActorUtils.h"
 
-#include <SMDS_SetIterator.hxx>
-#include <SMDS_Mesh.hxx>
-
 // SALOME GEOM includes
 #include <GEOMBase.h>
 #include <GEOM_Actor.h>
 // SALOME GUI includes
 #include <LightApp_SelectionMgr.h>
 #include <LightApp_UpdateFlags.h>
+#include <QtxComboBox.h>
 #include <SALOME_ListIO.hxx>
-#include <SVTK_ViewWindow.h>
+#include <SUIT_Desktop.h>
+#include <SUIT_MessageBox.h>
+#include <SUIT_OverrideCursor.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Session.h>
 #include <SVTK_ViewModel.h>
+#include <SVTK_ViewWindow.h>
 #include <SalomeApp_Application.h>
-#include <SUIT_ResourceMgr.h>
-#include <SUIT_OverrideCursor.h>
-#include <SUIT_MessageBox.h>
-#include <SUIT_Desktop.h>
-#include <QtxComboBox.h>
 
 // SALOME KERNEL includes
 #include <SALOMEDS_SObject.hxx>
 #include <SALOMEDSClient_SObject.hxx>
 #include <SALOMEDS_wrap.hxx>
+#include "utilities.h"
 
 #include CORBA_SERVER_HEADER(SMESH_Group)
 
 // OCCT includes
+#include <BRepBndLib.hxx>
+#include <BRepMesh_IncrementalMesh.hxx>
 #include <BRep_Tool.hxx>
+#include <Bnd_Box.hxx>
+#include <Poly_Triangulation.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
+#include <TopLoc_Location.hxx>
 #include <TopTools_IndexedMapOfShape.hxx>
 #include <TopoDS.hxx>
 
-#include <TopLoc_Location.hxx>
-#include <Poly_Triangulation.hxx>
-#include <Bnd_Box.hxx>
-#include <BRepBndLib.hxx>
-#include <BRepMesh_IncrementalMesh.hxx>
-
 #include <Standard_ErrorHandler.hxx>
 
 // Qt includes
 #define MARGIN  11
 
 #define COLONIZE(str)   (QString(str).contains(":") > 0 ? QString(str) : QString(str) + " :" )
+#define __SHAPE_RGB__ 250, 0, 250
 
 enum TCol {
   COL_ALGO = 0, COL_SHAPE, COL_ERROR, COL_SHAPEID, COL_PUBLISHED, COL_BAD_MESH, NB_COLUMNS
@@ -148,10 +148,10 @@ namespace SMESH
     {
       myProperty = vtkProperty::New();
       myProperty->SetRepresentationToWireframe();
-      myProperty->SetColor( 250, 0, 250 );
-      myProperty->SetAmbientColor( 250, 0, 250 );
-      myProperty->SetDiffuseColor( 250, 0, 250 );
-      //myProperty->SetSpecularColor( 250, 0, 250 );
+      myProperty->SetColor( __SHAPE_RGB__ );
+      myProperty->SetAmbientColor( __SHAPE_RGB__ );
+      myProperty->SetDiffuseColor( __SHAPE_RGB__ );
+      //myProperty->SetSpecularColor( __SHAPE_RGB__ );
       myProperty->SetLineWidth( 5 );
     }
     // -----------------------------------------------------------------------
@@ -272,20 +272,25 @@ namespace SMESH
     GEOM_Actor* getActor(const TopoDS_Shape& shape)
     {
       int index = myIndexToShape.FindIndex( shape ) - 1;
-      if ( index < 0 || index >= myActors.size() )
+      if ( index < 0 || index >= (int) myActors.size() )
         return 0;
       GEOM_Actor* & actor = myActors[ index ];
       if ( !actor ) {
         actor = GEOM_Actor::New();
         if ( actor ) {
           actor->SetShape(shape,0,0);
-          actor->SetProperty(myProperty);
-          actor->SetShadingProperty(myProperty);
-          actor->SetWireframeProperty(myProperty);
-          actor->SetPreviewProperty(myProperty);
+          // actor->SetProperty(myProperty);
+          // actor->SetShadingProperty(myProperty);
+          // actor->SetWireframeProperty(myProperty);
+          // actor->SetPreviewProperty(myProperty);
           actor->PickableOff();
-          //         if ( shape.ShapeType() == TopAbs_EDGE )
-          //           actor->SubShapeOn();
+          //
+          actor->SetWidth( myProperty->GetLineWidth() );
+          actor->SetIsosWidth( myProperty->GetLineWidth() );
+          actor->SetIsosColor( __SHAPE_RGB__ );
+          actor->SetColor( __SHAPE_RGB__ );
+          // if ( shape.ShapeType() == TopAbs_EDGE )
+          //   actor->SubShapeOn();
           myViewWindow->AddActor( actor );
         }
       }
@@ -382,7 +387,11 @@ namespace SMESH
         if ( !geom->_is_nil() ) {
           GEOM::ListOfLong_var list = geom->GetSubShapeIndices();
           if ( list->length() == 1 && list[0] == subShapeID )
-            subSO = it->Value();
+          {
+            GEOM::GEOM_Object_var mainGO = geom->GetMainShape();
+            if ( aMainShape->IsSame( mainGO ))
+              subSO = it->Value();
+          }
         }
       }
     }
@@ -439,8 +448,10 @@ namespace SMESH
   QString shapeText(int subShapeID, GEOM::GEOM_Object_var aMainShape )
   {
     QString text;
-    if ( _PTR(SObject) aSO = getSubShapeSO( subShapeID, aMainShape ))
-      text = aSO->GetName().c_str();
+    if ( _PTR(SObject) aSO = getSubShapeSO( subShapeID, aMainShape )) {
+      text  = aSO->GetName().c_str();
+      text += QString(" (%1)").arg( aSO->GetID().c_str() );
+    }
     else {
       text = QString("#%1").arg( subShapeID );
       GEOM::GEOM_Object_wrap shape = getSubShape( subShapeID, aMainShape );
@@ -482,7 +493,7 @@ namespace SMESH
 //=======================================================================
 
 SMESHGUI_ComputeDlg::SMESHGUI_ComputeDlg( QWidget* parent, bool ForEval )
- : SMESHGUI_Dialog( parent, false, true, Close/* | Help*/ )
+ : SMESHGUI_Dialog( parent, false, true, Close | Help )
 {
   QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame());
   aDlgLay->setMargin( 0 );
@@ -564,7 +575,11 @@ QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent, bool ForEval)
   myTable->hideColumn( COL_PUBLISHED );
   myTable->hideColumn( COL_SHAPEID );
   myTable->hideColumn( COL_BAD_MESH );
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
   myTable->horizontalHeader()->setResizeMode( COL_ERROR, QHeaderView::Interactive );
+#else
+  myTable->horizontalHeader()->setSectionResizeMode( COL_ERROR, QHeaderView::Interactive );
+#endif
   myTable->setWordWrap( true );
   myTable->horizontalHeader()->setStretchLastSection( true );
   myTable->setMinimumWidth( 500 );
@@ -613,8 +628,8 @@ QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent, bool ForEval)
 
   // add all widgets to aFrame
   QVBoxLayout* aLay = new QVBoxLayout(aFrame);
-  aLay->setMargin( 0 );
-  aLay->setSpacing( 0 );
+  aLay->setMargin( MARGIN );
+  aLay->setSpacing( SPACING );
   aLay->addWidget( aPixGrp );
   aLay->addWidget( nameBox );
   aLay->addWidget( myBriefInfo );
@@ -727,10 +742,11 @@ void SMESHGUI_ComputeDlg_QThread::cancel()
 //================================================================================
 //================================================================================
 
-SMESHGUI_ComputeDlg_QThreadQDialog::SMESHGUI_ComputeDlg_QThreadQDialog(QWidget             * parent,
-                                                                       SMESH::SMESH_Gen_var  gen,
-                                                                       SMESH::SMESH_Mesh_var mesh,
-                                                                       GEOM::GEOM_Object_var mainShape)
+SMESHGUI_ComputeDlg_QThreadQDialog::
+SMESHGUI_ComputeDlg_QThreadQDialog(QWidget             * parent,
+                                   SMESH::SMESH_Gen_var  gen,
+                                   SMESH::SMESH_Mesh_var mesh,
+                                   GEOM::GEOM_Object_var mainShape)
   : QDialog(parent,
             Qt::WindowSystemMenuHint |
             Qt::WindowCloseButtonHint |
@@ -882,7 +898,7 @@ void SMESHGUI_BaseComputeOp::computeMesh()
 #endif
       aCompErrors = gen->GetComputeErrors( myMesh, myMainShape );
       // check if there are memory problems
-      for ( int i = 0; (i < aCompErrors->length()) && !memoryLack; ++i )
+      for ( CORBA::ULong i = 0; (i < aCompErrors->length()) && !memoryLack; ++i )
         memoryLack = ( aCompErrors[ i ].code == SMESH::COMPERR_MEMORY_PB );
     }
     catch(const SALOME::SALOME_Exception & S_ex) {
@@ -895,7 +911,9 @@ void SMESHGUI_BaseComputeOp::computeMesh()
 
     // NPAL16631: if ( !memoryLack )
     {
-      SMESH::ModifiedMesh(aMeshSObj, !computeFailed, myMesh->NbNodes() == 0);
+      SMESH::ModifiedMesh( aMeshSObj,
+                           !computeFailed && aHypErrors.isEmpty(),
+                           myMesh->NbNodes() == 0);
       update( UF_ObjBrowser | UF_Model );
 
       // SHOW MESH
@@ -905,57 +923,115 @@ void SMESHGUI_BaseComputeOp::computeMesh()
       long limitSize = resMgr->integerValue( "SMESH", "update_limit", 500000 );
       int entities = SMESH_Actor::eAllEntity;
       int hidden = 0;
+      long nbElements = 0;
       if ( !memoryLack )
       {
-        if ( getSMESHGUI()->automaticUpdate( myMesh, &entities, &limitExceeded, &hidden ) )
+        // List of objects that will be updated automatically
+        typedef QList< QPair< SMESH::SMESH_IDSource_var, _PTR(SObject) > > TListOf_IDSrc_SObj;
+        TListOf_IDSrc_SObj aListToUpdate;
+        SMESH::SMESH_IDSource_var aMeshObj =
+          SMESH::SObjectToInterface<SMESH::SMESH_IDSource>( aMeshSObj );
+        // put Mesh into list
+        aListToUpdate.append( TListOf_IDSrc_SObj::value_type( aMeshObj, aMeshSObj ));
+        SMESH::submesh_array_var aSubMeshes = myMesh->GetSubMeshes();
+        // put SubMeshes into list
+        for ( CORBA::ULong i = 0; i < aSubMeshes->length(); i++ )
         {
-          try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
-            OCC_CATCH_SIGNALS;
-#endif
-            SMESH_Actor *anActor = SMESH::FindActorByObject( myMesh );
-            if ( !anActor ) anActor = SMESH::CreateActor( aMeshSObj->GetStudy(), aMeshSObj->GetID().c_str(), true );    
-            if ( anActor ) // actor is not created for an empty mesh
-            {
-              anActor->SetEntityMode( entities );
-              SMESH::DisplayActor( SMESH::GetActiveWindow(), anActor );
-            }
-            SMESH::Update(myIObject, true);
-
-            if ( limitExceeded )
-            {
-              QStringList hiddenMsg;
-              if ( hidden & SMESH_Actor::e0DElements ) hiddenMsg << tr( "SMESH_ELEMS0D" );
-              if ( hidden & SMESH_Actor::eEdges )      hiddenMsg << tr( "SMESH_EDGES" );
-              if ( hidden & SMESH_Actor::eFaces )      hiddenMsg << tr( "SMESH_FACES" );
-              if ( hidden & SMESH_Actor::eVolumes )    hiddenMsg << tr( "SMESH_VOLUMES" );
-              if ( hidden & SMESH_Actor::eBallElem )   hiddenMsg << tr( "SMESH_BALLS" );
-              SUIT_MessageBox::warning( desktop(),
-                                        tr( "SMESH_WRN_WARNING" ),
-                                        tr( "SMESH_WRN_SIZE_INC_LIMIT_EXCEEDED" ).arg( myMesh->NbElements() ).arg( limitSize ).arg( hiddenMsg.join(", ") ) );
+          SMESH::SMESH_subMesh_var sm = aSubMeshes[i];
+          if ( CORBA::is_nil( sm ) ) continue;
+          _PTR(SObject) smSObj = SMESH::ObjectToSObject( sm );
+          if ( !smSObj ) continue;
+          SMESH::SMESH_IDSource_var aSubMeshObj =
+            SMESH::SObjectToInterface<SMESH::SMESH_IDSource>( smSObj );
+          SMESH_Actor *anActor = SMESH::FindActorByObject( aSubMeshObj );
+          if ( anActor && anActor->GetVisibility() )
+            aListToUpdate.append( TListOf_IDSrc_SObj::value_type( aSubMeshObj, smSObj ));
+        }
+        // put Groups into list
+        SMESH::ListOfGroups_var aGroups = myMesh->GetGroups();
+        for ( size_t i = 0; i < aGroups->length(); ++i )
+        {
+          SMESH::SMESH_GroupBase_var aGrp = aGroups[i];
+          if ( CORBA::is_nil( aGrp ) ) continue;
+          SMESH::SMESH_Group_var  aStdGroup  = SMESH::SMESH_Group::_narrow( aGrp );
+          if ( !aStdGroup->_is_nil() ) continue; // don't update standalone groups
+          _PTR(SObject) aGroupSO = SMESH::FindSObject( aGrp );
+          if ( !aGroupSO ) continue;
+          SMESH::SMESH_IDSource_var aGroupObj =
+            SMESH::SObjectToInterface<SMESH::SMESH_IDSource>( aGroupSO );
+          SMESH_Actor *anActor = SMESH::FindActorByObject( aGroupObj );
+          if ( anActor && anActor->GetVisibility() )
+            aListToUpdate.append( TListOf_IDSrc_SObj::value_type( aGroupObj, aGroupSO ));
+        }
+
+        // update mesh, sub-mesh and groups, if it's possible
+        TListOf_IDSrc_SObj::iterator anIter;
+        for ( anIter = aListToUpdate.begin(); anIter != aListToUpdate.end(); anIter++ )
+        {
+          SMESH::SMESH_Mesh_var aMesh =
+            SMESH::SMESH_Mesh::_narrow( SMESH::SObjectToObject( (*anIter).second ));
+
+          if ( getSMESHGUI()->automaticUpdate( (*anIter).first, &entities, &limitExceeded,
+                                               &hidden, &nbElements ) )
+          {
+            try {
+              OCC_CATCH_SIGNALS;
+              bool toDisplay = false;
+              if ( !aMesh->_is_nil() ) // display only a mesh
+              {
+                toDisplay = true;
+                SMESH_Actor *anActor = SMESH::FindActorByObject( aMesh );
+                if ( !anActor ) anActor = SMESH::CreateActor( (*anIter).second->GetStudy(),
+                                                              (*anIter).second->GetID().c_str(),
+                                                              /*clearLog =*/ true );
+                if ( anActor ) // actor is not created for an empty mesh
+                {
+                  anActor->SetEntityMode( entities );
+                  SMESH::DisplayActor( SMESH::GetActiveWindow(), anActor );
+                }
+              }
+              Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject
+                ( (*anIter).second->GetID().c_str(), "SMESH", (*anIter).second->GetName().c_str() );
+              SMESH::Update(anIO, toDisplay);
+
+              if ( limitExceeded && !aMesh->_is_nil() )
+              {
+                QStringList hiddenMsg;
+                if ( hidden & SMESH_Actor::e0DElements ) hiddenMsg << tr( "SMESH_ELEMS0D" );
+                if ( hidden & SMESH_Actor::eEdges )      hiddenMsg << tr( "SMESH_EDGES" );
+                if ( hidden & SMESH_Actor::eFaces )      hiddenMsg << tr( "SMESH_FACES" );
+                if ( hidden & SMESH_Actor::eVolumes )    hiddenMsg << tr( "SMESH_VOLUMES" );
+                if ( hidden & SMESH_Actor::eBallElem )   hiddenMsg << tr( "SMESH_BALLS" );
+                SUIT_MessageBox::warning( desktop(),
+                                          tr( "SMESH_WRN_WARNING" ),
+                                          tr( "SMESH_WRN_SIZE_INC_LIMIT_EXCEEDED" ).
+                                          arg( nbElements ).
+                                          arg( limitSize ).
+                                          arg( hiddenMsg.join(", ")));
+              }
             }
-          }
-          catch (...) {
+            catch (...) {
 #ifdef _DEBUG_
-            MESSAGE ( "Exception thrown during mesh visualization" );
+              MESSAGE ( "Exception thrown during mesh visualization" );
 #endif
-            if ( SMDS_Mesh::CheckMemory(true) ) { // has memory to show warning?
-              SMESH::OnVisuException();
-            }
-            else {
-              memoryLack = true;
+              if ( SMDS_Mesh::CheckMemory(true) ) { // has memory to show warning?
+                SMESH::OnVisuException();
+              }
+              else {
+                memoryLack = true;
+              }
             }
           }
-        }
-        else if ( limitExceeded )
-        {
-          SUIT_MessageBox::warning( desktop(),
-                                    tr( "SMESH_WRN_WARNING" ),
-                                    tr( "SMESH_WRN_SIZE_LIMIT_EXCEEDED" ).arg( myMesh->NbElements() ).arg( limitSize ) );
+          else if ( limitExceeded && !aMesh->_is_nil() )
+          {
+            SUIT_MessageBox::warning( desktop(),
+                                      tr( "SMESH_WRN_WARNING" ),
+                                      tr( "SMESH_WRN_SIZE_LIMIT_EXCEEDED" ).
+                                      arg( nbElements ).arg( limitSize ) );
+          }
         }
       }
-      LightApp_SelectionMgr *Sel = selectionMgr();
-      if ( Sel )
+      if ( LightApp_SelectionMgr *Sel = selectionMgr() )
       {
         SALOME_ListIO selected;
         selected.Append( myIObject );
@@ -967,10 +1043,11 @@ void SMESHGUI_BaseComputeOp::computeMesh()
   if ( memoryLack )
     aMemoryReserve.release();
 
-  myCompDlg->setWindowTitle(tr( computeFailed ? "SMESH_WRN_COMPUTE_FAILED" : "SMESH_COMPUTE_SUCCEED"));
+  myCompDlg->setWindowTitle
+    ( tr( computeFailed ? "SMESH_WRN_COMPUTE_FAILED" : "SMESH_COMPUTE_SUCCEED" ));
 
   // SHOW ERRORS
-  
+
   bool noCompError = ( !aCompErrors.operator->() || aCompErrors->length() == 0 );
   bool noHypoError = ( aHypErrors.isEmpty() );
 
@@ -1031,7 +1108,7 @@ void SMESHGUI_BaseComputeOp::showComputeResult( const bool theMemoryLack,
   else
   {
     bool onlyWarnings = !theNoCompError; // == valid mesh computed but there are errors reported
-    for ( int i = 0; i < theCompErrors->length() && onlyWarnings; ++i )
+    for ( CORBA::ULong i = 0; i < theCompErrors->length() && onlyWarnings; ++i )
       onlyWarnings = ( theCompErrors[ i ].code == SMESH::COMPERR_WARNING ||
                        theCompErrors[ i ].code == SMESH::COMPERR_NO_MESH_ON_SHAPE );
 
@@ -1086,7 +1163,7 @@ void SMESHGUI_BaseComputeOp::showComputeResult( const bool theMemoryLack,
       tbl->setColumnWidth( COL_ERROR, 200 );
 
       bool hasBadMesh = false;
-      for ( int row = 0; row < theCompErrors->length(); ++row )
+      for ( int row = 0; row < (int) theCompErrors->length(); ++row )
       {
         SMESH::ComputeError & err = theCompErrors[ row ];
 
@@ -1171,6 +1248,7 @@ void SMESHGUI_BaseComputeOp::onPublishShape()
   GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen();
   SALOMEDS::Study_var study = SMESHGUI::GetSMESHGen()->GetCurrentStudy();
 
+  QStringList entryList;
   QList<int> rows;
   SMESH::getSelectedRows( table(), rows );
   int row;
@@ -1183,15 +1261,17 @@ void SMESHGUI_BaseComputeOp::onPublishShape()
       if ( !SMESH::getSubShapeSO( 1, myMainShape )) // the main shape not published
       {
         QString name = GEOMBase::GetDefaultName( SMESH::shapeTypeName( myMainShape, "MAIN_SHAPE" ));
-        SALOMEDS::SObject_wrap so =
-          geomGen->AddInStudy( study, myMainShape, name.toLatin1().data(), GEOM::GEOM_Object::_nil());
+        SALOMEDS::SObject_wrap so = geomGen->AddInStudy( study, myMainShape,
+                                                         name.toLatin1().data(),
+                                                         GEOM::GEOM_Object::_nil());
         // look for myMainShape in the table
         for ( int r = 0, nr = table()->rowCount(); r < nr; ++r ) {
           if ( table()->item( r, COL_SHAPEID )->text() == "1" ) {
             if ( so->_is_nil() ) {
               CORBA::String_var name  = so->GetName();
               CORBA::String_var entry = so->GetID();
-              table()->item( r, COL_SHAPE     )->setText( name.in() );
+              QString       shapeText = QString("%1 (%2)").arg( name.in() ).arg( entry.in() );
+              table()->item( r, COL_SHAPE     )->setText( shapeText );
               table()->item( r, COL_PUBLISHED )->setText( entry.in() );
             }
             break;
@@ -1200,16 +1280,21 @@ void SMESHGUI_BaseComputeOp::onPublishShape()
         if ( curSub == 1 ) continue;
       }
       QString name = GEOMBase::GetDefaultName( SMESH::shapeTypeName( shape, "ERROR_SHAPE" ));
-      SALOMEDS::SObject_wrap so = geomGen->AddInStudy( study, shape, name.toLatin1().data(), myMainShape);
+      SALOMEDS::SObject_wrap so = geomGen->AddInStudy( study, shape,
+                                                       name.toLatin1().data(), myMainShape);
       if ( !so->_is_nil() ) {
         CORBA::String_var name  = so->GetName();
         CORBA::String_var entry = so->GetID();
-        table()->item( row, COL_SHAPE     )->setText( name.in() );
+        QString       shapeText = QString("%1 (%2)").arg( name.in() ).arg( entry.in() );
+        table()->item( row, COL_SHAPE     )->setText( shapeText );
         table()->item( row, COL_PUBLISHED )->setText( entry.in() );
+        entryList.push_back( entry.in() );
       }
     }
   }
   getSMESHGUI()->getApp()->updateObjectBrowser();
+  getSMESHGUI()->getApp()->browseObjects( entryList, /*isApplyAndClose=*/true );
+
   currentCellChanged(); // to update buttons
 }
 
@@ -1426,6 +1511,7 @@ QTableWidget* SMESHGUI_BaseComputeOp::table()
 SMESHGUI_ComputeOp::SMESHGUI_ComputeOp()
  : SMESHGUI_BaseComputeOp()
 {
+  myHelpFileName = "constructing_meshes_page.html#compute_anchor";
 }
 
 
@@ -1485,17 +1571,16 @@ LightApp_Dialog* SMESHGUI_ComputeOp::dlg() const
 //================================================================================
 /*!
  * \brief Constructor
-*/
+ */
 //================================================================================
 
 SMESHGUI_PrecomputeOp::SMESHGUI_PrecomputeOp()
- : SMESHGUI_BaseComputeOp(),
myDlg( 0 ),
myOrderMgr( 0 ),
myActiveDlg( 0 ),
myPreviewDisplayer( 0 )
 : SMESHGUI_BaseComputeOp(),
   myActiveDlg( 0 ),
   myDlg( 0 ),
   myPreviewDisplayer( 0 ),
   myOrderMgr( 0 )
 {
-  myHelpFileName = "constructing_meshes_page.html#preview_mesh_anchor";
 }
 
 //================================================================================
@@ -1536,6 +1621,8 @@ LightApp_Dialog* SMESHGUI_PrecomputeOp::dlg() const
 
 void SMESHGUI_PrecomputeOp::startOperation()
 {
+  myHelpFileName = "constructing_meshes_page.html#preview_anchor"; // other anchor onCompute()
+
   if ( !myDlg )
   {
     myDlg = new SMESHGUI_PrecomputeDlg( desktop() );
@@ -1652,7 +1739,7 @@ void SMESHGUI_PrecomputeOp::initDialog()
   myOrderMgr = new SMESHGUI_MeshOrderMgr( myDlg->getMeshOrderBox() );
   myOrderMgr->SetMesh( myMesh );
   bool isOrder = myOrderMgr->GetMeshOrder(myPrevOrder);
-  myDlg->getMeshOrderBox()->setShown(isOrder);
+  myDlg->getMeshOrderBox()->setVisible(isOrder);
   if ( !isOrder ) {
     delete myOrderMgr;
     myOrderMgr = 0;
@@ -1670,13 +1757,14 @@ void SMESHGUI_PrecomputeOp::initDialog()
 void SMESHGUI_PrecomputeOp::getAssignedAlgos(_PTR(SObject) theMesh,
                                              QMap<int,int>& theModeMap)
 {
-  _PTR(SObject)          aHypRoot;
+  if ( !theMesh ) return;
+  _PTR(SObject)          aHypFolder;
   _PTR(GenericAttribute) anAttr;
   int aPart = SMESH::Tag_RefOnAppliedAlgorithms;
-  if ( theMesh && theMesh->FindSubObject( aPart, aHypRoot ) )
+  if ( theMesh->FindSubObject( aPart, aHypFolder ) )
   {
     _PTR(ChildIterator) anIter =
-      SMESH::GetActiveStudyDocument()->NewChildIterator( aHypRoot );
+      SMESH::GetActiveStudyDocument()->NewChildIterator( aHypFolder );
     for ( ; anIter->More(); anIter->Next() )
     {
       _PTR(SObject) anObj = anIter->Value();
@@ -1685,16 +1773,16 @@ void SMESHGUI_PrecomputeOp::getAssignedAlgos(_PTR(SObject) theMesh,
         anObj = aRefObj;
       else
         continue;
-      
+
       if ( anObj->FindAttribute( anAttr, "AttributeName" ) )
       {
         CORBA::Object_var aVar = _CAST(SObject,anObj)->GetObject();
         if ( CORBA::is_nil( aVar ) )
           continue;
-        
+
+        SMESH::SMESH_Algo_var algo;
         for( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ )
         {
-          SMESH::SMESH_Algo_var algo;
           switch(dim) {
           case SMESH::DIM_1D: algo = SMESH::SMESH_1D_Algo::_narrow( aVar ); break;
           case SMESH::DIM_2D: algo = SMESH::SMESH_2D_Algo::_narrow( aVar ); break;
@@ -1702,7 +1790,56 @@ void SMESHGUI_PrecomputeOp::getAssignedAlgos(_PTR(SObject) theMesh,
           default: break;
           }
           if ( !algo->_is_nil() )
+          {
             theModeMap[ dim ] = 0;
+            if ( theModeMap.size() == 3 )
+              return;
+            break;
+          }
+        }
+      }
+    }
+  }
+
+  // check sub-meshes
+  for ( aPart = SMESH::Tag_SubMeshOnEdge; aPart <= SMESH::Tag_LastSubMesh; ++aPart )
+  {
+    if ( !theMesh->FindSubObject( aPart, aHypFolder ))
+      continue;
+
+    _PTR(ChildIterator) anIter =
+      SMESH::GetActiveStudyDocument()->NewChildIterator( aHypFolder );
+    for ( anIter->InitEx(true); anIter->More(); anIter->Next() )
+    {
+      _PTR(SObject) anObj = anIter->Value();
+      _PTR(SObject) aRefObj;
+      if ( anObj->ReferencedObject( aRefObj ) )
+        anObj = aRefObj;
+      else
+        continue;
+
+      if ( anObj->FindAttribute( anAttr, "AttributeName" ))
+      {
+        CORBA::Object_var aVar = _CAST(SObject,anObj)->GetObject();
+        if ( CORBA::is_nil( aVar ) )
+          continue;
+
+        SMESH::SMESH_Algo_var algo;
+        for( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ )
+        {
+          switch(dim) {
+          case SMESH::DIM_1D: algo = SMESH::SMESH_1D_Algo::_narrow( aVar ); break;
+          case SMESH::DIM_2D: algo = SMESH::SMESH_2D_Algo::_narrow( aVar ); break;
+          case SMESH::DIM_3D: algo = SMESH::SMESH_3D_Algo::_narrow( aVar ); break;
+          default: break;
+          }
+          if ( !algo->_is_nil() )
+          {
+            theModeMap[ dim ] = 0;
+            if ( theModeMap.size() == 3 )
+              return;
+            break;
+          }
         }
       }
     }
@@ -1722,6 +1859,7 @@ void SMESHGUI_PrecomputeOp::onCompute()
     myOrderMgr->SetMeshOrder();
   myMapShapeId.clear();
   myActiveDlg = computeDlg();
+  myHelpFileName = "constructing_meshes_page.html#compute_anchor";
   computeMesh();
 }
 
@@ -1752,7 +1890,7 @@ void SMESHGUI_PrecomputeOp::onCancel()
       // remove all submeshes for collected shapes
       QMap<int,int>::const_iterator it = myMapShapeId.constBegin();
       for ( ; it != myMapShapeId.constEnd(); ++it )
-        myMesh->ClearSubMesh( *it );
+        myMesh->ClearSubMesh( it.key() );
       isRestoreOrder = true;
     }
   }
@@ -1794,19 +1932,19 @@ void SMESHGUI_PrecomputeOp::onPreview()
   if (myOrderMgr && myOrderMgr->IsOrderChanged())
     myOrderMgr->SetMeshOrder();
 
-  // Compute preview of mesh, 
+  // Compute preview of mesh,
   // i.e. compute mesh till indicated dimension
   int dim = myDlg->getPreviewMode();
-  
+
   SMESH::MemoryReserve aMemoryReserve;
-  
+
   SMESH::compute_error_array_var aCompErrors;
   QString                        aHypErrors;
 
   bool computeFailed = true, memoryLack = false;
 
   SMESHGUI_ComputeDlg* aCompDlg = computeDlg();
-    aCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() );
+  aCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() );
 
   SMESHGUI* gui = getSMESHGUI();
   SMESH::SMESH_Gen_var gen = gui->GetSMESHGen();
@@ -1853,7 +1991,7 @@ void SMESHGUI_PrecomputeOp::onPreview()
 #endif
     aCompErrors = gen->GetComputeErrors( myMesh, myMainShape );
     // check if there are memory problems
-    for ( int i = 0; (i < aCompErrors->length()) && !memoryLack; ++i )
+    for ( CORBA::ULong i = 0; (i < aCompErrors->length()) && !memoryLack; ++i )
       memoryLack = ( aCompErrors[ i ].code == SMESH::COMPERR_MEMORY_PB );
   }
   catch(const SALOME::SALOME_Exception & S_ex){
@@ -1886,7 +2024,8 @@ void SMESHGUI_PrecomputeOp::onPreview()
   if ( isShowError )
   {
     myDlg->hide();
-    aCompDlg->setWindowTitle(tr( computeFailed ? "SMESH_WRN_COMPUTE_FAILED" : "SMESH_COMPUTE_SUCCEED"));
+    aCompDlg->setWindowTitle
+      ( tr( computeFailed ? "SMESH_WRN_COMPUTE_FAILED" : "SMESH_COMPUTE_SUCCEED" ));
     showComputeResult( memoryLack, noCompError, aCompErrors, noHypoError, aHypErrors );
   }
 }
@@ -1906,6 +2045,7 @@ SMESHGUI_PrecomputeDlg::SMESHGUI_PrecomputeDlg( QWidget* parent )
 
   setButtonText( OK, tr( "COMPUTE" ) );
   QFrame* main = mainFrame();
+  main->setMinimumWidth( 300 );
 
   QVBoxLayout* layout = new QVBoxLayout( main );
 
@@ -1965,7 +2105,7 @@ void SMESHGUI_PrecomputeDlg::setPreviewModes( const QList<int>& theModes )
 
 int SMESHGUI_PrecomputeDlg::getPreviewMode() const
 {
-  return myPreviewMode->currentId();
+  return myPreviewMode->currentId().toInt();
 }
 
 //================================================================================
@@ -1989,6 +2129,7 @@ SMESHGUI_MeshOrderBox* SMESHGUI_PrecomputeDlg::getMeshOrderBox() const
 SMESHGUI_EvaluateOp::SMESHGUI_EvaluateOp()
  : SMESHGUI_BaseComputeOp()
 {
+  myHelpFileName = "constructing_meshes_page.html#evaluate_anchor";
 }
 
 
@@ -2087,10 +2228,11 @@ void SMESHGUI_BaseComputeOp::evaluateMesh()
     aMemoryReserve.release();
 
   evaluateFailed =  ( aCompErrors->length() > 0 );
-  myCompDlg->setWindowTitle(tr( evaluateFailed ? "SMESH_WRN_EVALUATE_FAILED" : "SMESH_EVALUATE_SUCCEED"));
+  myCompDlg->setWindowTitle
+    ( tr( evaluateFailed ? "SMESH_WRN_EVALUATE_FAILED" : "SMESH_EVALUATE_SUCCEED" ));
 
   // SHOW ERRORS
-  
+
   bool noCompError = ( !aCompErrors.operator->() || aCompErrors->length() == 0 );
   bool noHypoError = ( aHypErrors.isEmpty() );
 
@@ -2182,7 +2324,7 @@ void SMESHGUI_BaseComputeOp::showEvaluateResult(const SMESH::long_array& theRes,
       tbl->setColumnWidth( COL_ERROR, 200 );
 
       bool hasBadMesh = false;
-      for ( int row = 0; row < theCompErrors->length(); ++row )
+      for ( int row = 0; row < (int) theCompErrors->length(); ++row )
       {
         SMESH::ComputeError & err = theCompErrors[ row ];