Salome HOME
IPAL54529: Hexahedron(ijk) fails on a block with composite sides if Viscous Layers...
authoreap <eap@opencascade.com>
Fri, 12 Jul 2019 12:15:38 +0000 (15:15 +0300)
committereap <eap@opencascade.com>
Fri, 12 Jul 2019 12:15:38 +0000 (15:15 +0300)
+ In Create Mesh dialog define enabled tabs by SMESH_Algo::IsApplicable( shape )
+ Extract SMESH_Indexer from StdMeshers_HexaFromSkin_3D.cxx

35 files changed:
doc/salome/examples/defining_hypotheses_ex14.py
doc/salome/examples/defining_hypotheses_ex15.py
src/SMESH/SMESH_Algo.hxx
src/SMESHGUI/SMESHGUI_Hypotheses.cxx
src/SMESHGUI/SMESHGUI_Hypotheses.h
src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx
src/SMESHGUI/SMESHGUI_MeshDlg.cxx
src/SMESHGUI/SMESHGUI_MeshDlg.h
src/SMESHGUI/SMESHGUI_MeshOp.cxx
src/SMESHGUI/SMESHGUI_MeshOp.h
src/SMESHGUI/SMESH_msg_en.ts
src/SMESHUtils/CMakeLists.txt
src/SMESHUtils/SMESH_Delaunay.cxx
src/SMESHUtils/SMESH_Indexer.hxx [new file with mode: 0644]
src/SMESHUtils/SMESH_TypeDefs.hxx
src/SMESH_I/SMESH_Gen_i.cxx
src/SMESH_I/SMESH_Hypothesis_i.cxx
src/SMESH_I/SMESH_Hypothesis_i.hxx
src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx
src/StdMeshers/StdMeshers_QuadrangleParams.cxx
src/StdMeshers/StdMeshers_QuadrangleParams.hxx
src/StdMeshers/StdMeshers_Quadrangle_2D.cxx
src/StdMeshers_I/StdMeshers_Hexa_3D_i.cxx
src/StdMeshers_I/StdMeshers_Hexa_3D_i.hxx
src/StdMeshers_I/StdMeshers_Prism_3D_i.cxx
src/StdMeshers_I/StdMeshers_Prism_3D_i.hxx
src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.cxx
src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.hxx
src/StdMeshers_I/StdMeshers_QuadrangleParams_i.cxx
src/StdMeshers_I/StdMeshers_QuadrangleParams_i.hxx
src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.cxx
src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.hxx
src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.cxx
src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.hxx
src/StdMeshers_I/StdMeshers_i.cxx

index b0ef9f6..d33e1e1 100644 (file)
@@ -2,11 +2,10 @@
 
 import salome
 salome.salome_init()
-import GEOM
+
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
 
-import SMESH, SALOMEDS
 from salome.smesh import smeshBuilder
 smesh =  smeshBuilder.New()
 
@@ -14,20 +13,20 @@ smesh =  smeshBuilder.New()
 Box_1 = geompy.MakeBoxDXDYDZ(100, 100, 100)
 Disk_1 = geompy.MakeDiskR(100, 1)
 Common_1 = geompy.MakeCommon(Disk_1, Box_1)
-geompy.addToStudy( Disk_1, "Disk_1" )
-geompy.addToStudy( Box_1, "Box_1" )
+triaVertex = geompy.GetVertexNearPoint( Common_1, geompy.MakeVertex(0,0,0) )
 geompy.addToStudy( Common_1, "Common_1" )
+geompy.addToStudyInFather( Common_1, triaVertex, "triaVertex" )
+
 
 # Set the Geometry for meshing
 Mesh_1 = smesh.Mesh(Common_1)
 
-
-# Define 1D hypothesis and compute the mesh
+# Define 1D hypothesis
 Regular_1D = Mesh_1.Segment()
 Nb_Segments_1 = Regular_1D.NumberOfSegments(10)
-Nb_Segments_1.SetDistrType( 0 )
 
 # Create Quadrangle parameters and define the Base Vertex.
-Quadrangle_2D = Mesh_1.Quadrangle().TriangleVertex( 8 )
+Quadrangle_2D = Mesh_1.Quadrangle().TriangleVertex( triaVertex )
 
+# Compute the mesh
 Mesh_1.Compute()
index 80b430e..5a32a1d 100644 (file)
@@ -2,14 +2,10 @@
 
 import salome
 salome.salome_init()
-import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
-
-import SMESH, SALOMEDS
 from salome.smesh import smeshBuilder
 smesh =  smeshBuilder.New()
-from salome.StdMeshers import StdMeshersBuilder
 
 # Make quadrangle face and explode it on edges.
 Vertex_1 = geompy.MakeVertex(0, 0, 0)
@@ -18,10 +14,6 @@ Vertex_3 = geompy.MakeVertex(40, 30, 0)
 Vertex_4 = geompy.MakeVertex(0, 30, 0)
 Quadrangle_Face_1 = geompy.MakeQuad4Vertices(Vertex_1, Vertex_4, Vertex_3, Vertex_2)
 [Edge_1,Edge_2,Edge_3,Edge_4] = geompy.SubShapeAllSorted(Quadrangle_Face_1, geompy.ShapeType["EDGE"])
-geompy.addToStudy( Vertex_1, "Vertex_1" )
-geompy.addToStudy( Vertex_2, "Vertex_2" )
-geompy.addToStudy( Vertex_3, "Vertex_3" )
-geompy.addToStudy( Vertex_4, "Vertex_4" )
 geompy.addToStudy( Quadrangle_Face_1, "Quadrangle Face_1" )
 geompy.addToStudyInFather( Quadrangle_Face_1, Edge_2, "Edge_2" )
 
@@ -30,25 +22,20 @@ Mesh_1 = smesh.Mesh(Quadrangle_Face_1)
 
 # Create Quadrangle parameters and
 # define the Type as Quadrangle Preference
-Quadrangle_Parameters_1 = smesh.CreateHypothesis('QuadrangleParams')
-Quadrangle_Parameters_1.SetQuadType( StdMeshersBuilder.QUAD_QUADRANGLE_PREF )
+Quad_algo = Mesh_1.Quadrangle()
+Quadrangle_Parameters_1 = Quad_algo.QuadrangleParameters( smeshBuilder.QUAD_QUADRANGLE_PREF )
 
 # Define other hypotheses and algorithms
 Regular_1D = Mesh_1.Segment()
 Nb_Segments_1 = Regular_1D.NumberOfSegments(4)
-Nb_Segments_1.SetDistrType( 0 )
-status = Mesh_1.AddHypothesis(Quadrangle_Parameters_1)
-Quadrangle_2D = Mesh_1.Quadrangle()
 
 # Define submesh on one edge to provide different number of segments
 Regular_1D_1 = Mesh_1.Segment(geom=Edge_2)
 Nb_Segments_2 = Regular_1D_1.NumberOfSegments(10)
-Nb_Segments_2.SetDistrType( 0 )
-SubMesh_1 = Regular_1D_1.GetSubMesh()
 
 # Compute mesh (with Quadrangle Preference type)
 isDone = Mesh_1.Compute()
 
 # Change type to Reduced and compute again
-Quadrangle_Parameters_1.SetQuadType( StdMeshersBuilder.QUAD_REDUCED )
+Quadrangle_Parameters_1.SetQuadType( smeshBuilder.QUAD_REDUCED )
 isDone = Mesh_1.Compute()
index e35a471..85ba384 100644 (file)
@@ -89,6 +89,7 @@ class SMESH_EXPORT SMESH_Algo : public SMESH_Hypothesis
     std::set<SMDSAbs_GeometryType> _outElemTypes; // produced types of mesh elements
     std::string                    _label;        // GUI type name
 
+    Features(): _dim( -1 ) {}
     bool IsCompatible( const Features& algo2 ) const;
   };
   /*!
index db3aa0e..5940ed7 100644 (file)
@@ -830,7 +830,7 @@ bool HypothesesSet::isAlgo() const
 void HypothesesSet::init( bool isAlgo )
 {
   myIsAlgo = isAlgo;
-  myIndex = -1;
+  myIndex = 0;
 }
 
 bool HypothesesSet::more() const
@@ -864,8 +864,7 @@ int HypothesesSet::maxDim() const
   int dim = -1;
   for ( int isAlgo = 0; isAlgo < 2; ++isAlgo )
   {
-    thisSet->init( isAlgo );
-    while ( thisSet->next(), thisSet->more() )
+    for ( thisSet->init( isAlgo ); thisSet->more(); thisSet->next() )
       if ( HypothesisData* hypData = SMESH::GetHypothesisData( thisSet->current() ))
         for ( int i = 0; i < hypData->Dim.count(); ++i )
           dim = qMax( dim, hypData->Dim[i] );
index 1485806..e75b822 100644 (file)
@@ -228,9 +228,8 @@ public:
 
   bool isAlgo() const;
 
-  //this method sets internal index to -1, thus before any data access it is necessary to call next()
+  // CASCADE-like iteration
   void init( bool );
-
   bool more() const;
   void next();
   QString current() const;
index 96055aa..eaaad91 100644 (file)
@@ -668,7 +668,7 @@ namespace SMESH
     int res = SMESH::HYP_UNKNOWN_FATAL;
     SUIT_OverrideCursor wc;
 
-    if (!aSubMesh->_is_nil() && ! aHyp->_is_nil()) {
+    if ( !aSubMesh->_is_nil() && !aHyp->_is_nil() ) {
       try {
         SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
         _PTR(SObject) SsubM = SMESH::FindSObject(aSubMesh);
index adc8a64..a1ee4ec 100644 (file)
@@ -830,6 +830,17 @@ bool SMESHGUI_MeshDlg::isTabEnabled(const int theTabId) const
 
 //================================================================================
 /*!
+ * \brief Return index of a current tab
+ * \return tab ID
+ */
+//================================================================================
+int SMESHGUI_MeshDlg::currentTab() const
+{
+  return Dim3D - myTabWg->currentIndex();
+}
+
+//================================================================================
+/*!
  * \brief SLOT called when a Geom selection button is clicked
  */
 //================================================================================
@@ -900,5 +911,8 @@ int SMESHGUI_MeshDlg::currentMeshType( )
 //================================================================================
 void SMESHGUI_MeshDlg::setCurrentMeshType( const int theIndex )
 {
-  myMeshType->setCurrentIndex( theIndex );
+  if ( theIndex < myMeshType->count() )
+    myMeshType->setCurrentIndex( theIndex );
+  else
+    myMeshType->setCurrentIndex( 0 );
 }
index d079956..3dd5b06 100644 (file)
@@ -66,20 +66,23 @@ public:
   SMESHGUI_MeshDlg( const bool, const bool );
   virtual ~SMESHGUI_MeshDlg();
   
-  SMESHGUI_MeshTab*            tab( const int ) const;
   void                         reset();
-  void                         setCurrentTab( const int );
-  void                         setMaxHypoDim( const int );
+  void                         setTitile( const bool, const bool );
   void                         setHypoSets( const QStringList& );
   void                         setGeomPopupEnabled( const bool );
-  void                         disableTab(const int);
+  int                          getActiveObject();
+
+  SMESHGUI_MeshTab*            tab( const int ) const;
   void                         enableTab(const int);
+  void                         disableTab(const int);
   bool                         isTabEnabled(const int) const;
-  int                          getActiveObject();
+  void                         setCurrentTab( const int );
+  int                          currentTab() const;
+  void                         setMaxHypoDim( const int );
+
   void                         setAvailableMeshType(const QStringList& );
-  int                          currentMeshType();
   void                         setCurrentMeshType( const int );
-  void                         setTitile( const bool, const bool );
+  int                          currentMeshType();
 
 signals:
   void                         hypoSet( const QString& );
index a49979d..5d097f2 100644 (file)
 #include <TopExp_Explorer.hxx>
 #include <BRep_Tool.hxx>
 
-// IDL includes
-#include <SALOMEconfig.h>
-#include CORBA_CLIENT_HEADER(SMESH_Gen)
-
 //================================================================================
 /*!
  * \brief Constructor
@@ -92,8 +88,7 @@ SMESHGUI_MeshOp::SMESHGUI_MeshOp( const bool theToCreate, const bool theIsMesh )
   myShapeByMeshOp( 0 ),
   myToCreate( theToCreate ),
   myIsMesh( theIsMesh ),
-  myIsInvalidSubMesh( false ),
-  myHypoSet( 0 )
+  myIsInvalidSubMesh( false )
 {
   if ( GeometryGUI::GetGeomGen()->_is_nil() )// check that GEOM_Gen exists
     GeometryGUI::InitGeomGen();
@@ -218,6 +213,7 @@ void SMESHGUI_MeshOp::startOperation()
     connect( myDlg, SIGNAL( hypoSet( const QString& )), SLOT( onHypoSet( const QString& )));
     connect( myDlg, SIGNAL( geomSelectionByMesh( bool )), SLOT( onGeomSelectionByMesh( bool )));
     connect( myDlg, SIGNAL( selectMeshType( const int, const int ) ), SLOT( onAlgoSetByMeshType( const int, const int)));
+
     if ( myToCreate ) {
       if ( myIsMesh ) myHelpFileName = "constructing_meshes.html";
       else            myHelpFileName = "constructing_submeshes.html";
@@ -227,22 +223,20 @@ void SMESHGUI_MeshOp::startOperation()
     }
   }
   SMESHGUI_SelectionOp::startOperation();
-  // iterate through dimensions and get available algorithms, set them to the dialog
-  _PTR(SComponent) aFather = SMESH::getStudy()->FindComponent( "SMESH" );
+
+  // clear available hypotheses
+  QStringList hypList;
   for ( int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++ )
   {
     SMESHGUI_MeshTab* aTab = myDlg->tab( i );
-    QStringList hypList;
-    // clear available hypotheses
+    // set algos
+    aTab->setAvailableHyps( Algo, hypList );
     aTab->setAvailableHyps( MainHyp, hypList );
     aTab->setAvailableHyps( AddHyp, hypList );
     aTab->setExistingHyps( MainHyp, hypList );
     aTab->setExistingHyps( AddHyp, hypList );
     myExistingHyps[ i ][ MainHyp ].clear();
     myExistingHyps[ i ][ AddHyp ].clear();
-    // set algos
-    availableHyps( i, Algo, hypList, myAvailableHypData[i][Algo] );
-    aTab->setAvailableHyps( Algo, hypList );
   }
   if ( myToCreate )
   {
@@ -253,18 +247,17 @@ void SMESHGUI_MeshOp::startOperation()
   {
     myDlg->activateObject( SMESHGUI_MeshDlg::Obj );
   }
-  myDlg->setCurrentTab( SMESH::DIM_3D );
 
-  QStringList TypeMeshList;
-  createMeshTypeList( TypeMeshList );
-  setAvailableMeshType( TypeMeshList );
+  updateMeshTypeList();
+  myDlg->setCurrentMeshType( MT_ANY );
 
-  myDlg->show();
+  myDlg->setCurrentTab( SMESH::DIM_3D );
   myDlg->setGeomPopupEnabled(false);
+  myDlg->show();
+
   selectionDone();
 
   myHasConcurrentSubBefore = false;
-
   myObjectToSelect.clear();
 }
 
@@ -446,7 +439,7 @@ char* SMESHGUI_MeshOp::isSubmeshIgnored() const
                !algo->IsSupportSubmeshes )
             return CORBA::string_dup( algoNames[0].toUtf8().data() );
         }
-//       }
+        //       }
     }
   }
   return 0;
@@ -460,42 +453,37 @@ char* SMESHGUI_MeshOp::isSubmeshIgnored() const
 //================================================================================
 _PTR(SObject) SMESHGUI_MeshOp::getSubmeshByGeom() const
 {
-  QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
-  QString aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
+  QString  aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
   _PTR(SObject) pMesh = SMESH::getStudy()->FindObjectID( aMeshEntry.toUtf8().data() );
-  _PTR(SObject) pGeom = SMESH::getStudy()->FindObjectID( aGeomEntry.toUtf8().data() );
-  if ( pMesh && pGeom ) {
-    GEOM::GEOM_Object_var geom = SMESH::SObjectToInterface<GEOM::GEOM_Object>( pGeom );
-    if ( !geom->_is_nil() ) {
-      int tag = -1;
-      switch ( geom->GetShapeType() ) {
-      case GEOM::VERTEX:   tag = SMESH::Tag_SubMeshOnVertex;   break;
-      case GEOM::EDGE:     tag = SMESH::Tag_SubMeshOnEdge;     break;
-      case GEOM::WIRE:     tag = SMESH::Tag_SubMeshOnWire;     break;
-      case GEOM::FACE:     tag = SMESH::Tag_SubMeshOnFace;     break;
-      case GEOM::SHELL:    tag = SMESH::Tag_SubMeshOnShell;    break;
-      case GEOM::SOLID:    tag = SMESH::Tag_SubMeshOnSolid;    break;
-      case GEOM::COMPOUND: tag = SMESH::Tag_SubMeshOnCompound; break;
-      default:;
-      }
-      _PTR(GenericAttribute) anAttr;
-      _PTR(SObject) aSubmeshRoot;
-      _PTR(Study) aStudy = SMESH::getStudy();
-      if ( pMesh->FindSubObject( tag, aSubmeshRoot ) )
+  if ( pMesh && !myGeom->_is_nil() ) {
+    int tag = -1;
+    switch ( myGeom->GetShapeType() ) {
+    case GEOM::VERTEX:   tag = SMESH::Tag_SubMeshOnVertex;   break;
+    case GEOM::EDGE:     tag = SMESH::Tag_SubMeshOnEdge;     break;
+    case GEOM::WIRE:     tag = SMESH::Tag_SubMeshOnWire;     break;
+    case GEOM::FACE:     tag = SMESH::Tag_SubMeshOnFace;     break;
+    case GEOM::SHELL:    tag = SMESH::Tag_SubMeshOnShell;    break;
+    case GEOM::SOLID:    tag = SMESH::Tag_SubMeshOnSolid;    break;
+    case GEOM::COMPOUND: tag = SMESH::Tag_SubMeshOnCompound; break;
+    default:;
+    }
+    _PTR(GenericAttribute) anAttr;
+    _PTR(SObject) aSubmeshRoot;
+    _PTR(Study) aStudy = SMESH::getStudy();
+    if ( pMesh->FindSubObject( tag, aSubmeshRoot ) )
+    {
+      _PTR(ChildIterator) smIter = aStudy->NewChildIterator( aSubmeshRoot );
+      for ( ; smIter->More(); smIter->Next() )
       {
-        _PTR(ChildIterator) smIter = aStudy->NewChildIterator( aSubmeshRoot );
-        for ( ; smIter->More(); smIter->Next() )
-        {
-          _PTR(SObject) aSmObj = smIter->Value();
-          if ( ! aSmObj->FindAttribute( anAttr, "AttributeIOR" ))
-            continue;
-          _PTR(ChildIterator) anIter1 = aStudy->NewChildIterator(aSmObj);
-          for ( ; anIter1->More(); anIter1->Next()) {
-            _PTR(SObject) pGeom2 = anIter1->Value();
-            if ( pGeom2->ReferencedObject( pGeom2 ) &&
-                 pGeom2->GetID() == pGeom->GetID() )
-              return aSmObj;
-          }
+        _PTR(SObject) aSmObj = smIter->Value();
+        if ( ! aSmObj->FindAttribute( anAttr, "AttributeIOR" ))
+          continue;
+        _PTR(ChildIterator) anIter1 = aStudy->NewChildIterator(aSmObj);
+        for ( ; anIter1->More(); anIter1->Next()) {
+          _PTR(SObject) pGeom2 = anIter1->Value();
+          if ( pGeom2->ReferencedObject( pGeom2 ) &&
+               myGeomEntry == pGeom2->GetID().c_str() )
+            return aSmObj;
         }
       }
     }
@@ -517,232 +505,130 @@ void SMESHGUI_MeshOp::selectionDone()
 
   SMESHGUI_SelectionOp::selectionDone();
 
+  myGeomEntry.clear();
+  myGeom = GEOM::GEOM_Object::_nil();
+  myIsInvalidSubMesh = false;
+  myIsOnGeometry = true;
+
   try
   {
-    myIsOnGeometry = true;
-    myIsInvalidSubMesh = false;
-
-    //Check geometry for mesh
-    QString anObjEntry = myDlg->selectedObject(SMESHGUI_MeshDlg::Obj);
-    _PTR(SObject) pObj = SMESH::getStudy()->FindObjectID(anObjEntry.toUtf8().data());
-    if (pObj)
+    // allow selecting multiple geom objects only for sub-mesh creation
+    QStringList aGEOMs;
+    myDlg->selectedObject( SMESHGUI_MeshDlg::Geom, aGEOMs );
+    int nbGeoms = aGEOMs.count();
+    if ( nbGeoms > 0 )
     {
-      SMESH::SMESH_Mesh_var aMeshVar =
-        SMESH::SMESH_Mesh::_narrow(_CAST(SObject,pObj)->GetObject());
-      if (!aMeshVar->_is_nil()) {
-        if (!myToCreate && !aMeshVar->HasShapeToMesh())
-          myIsOnGeometry = false;
+      myGeomEntry = aGEOMs[0];
+      _PTR(SObject) pGeom = SMESH::getStudy()->FindObjectID( myGeomEntry.toUtf8().data() );
+      if ( nbGeoms > 1 && myToCreate && myIsMesh )
+      {
+        selectObject( pGeom );
+        selectionDone();
+        return;
       }
+      myGeom = SMESH::SObjectToInterface< GEOM::GEOM_Object >( pGeom ); // creation case
     }
 
-    if (myIsOnGeometry)
-    {
-      // Enable tabs according to shape dimension
-
-      int shapeDim = 3;
+    QString anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
+    _PTR(SObject) pObj = SMESH::getStudy()->FindObjectID( anObjEntry.toUtf8().data() );
 
-      QStringList aGEOMs;
-      myDlg->selectedObject(SMESHGUI_MeshDlg::Geom, aGEOMs);
-      GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO;
+    SMESH::SMESH_Mesh_var    mesh = SMESH::SObjectToInterface< SMESH::SMESH_Mesh >( pObj );
+    SMESH::SMESH_subMesh_var subMesh;
 
-      if (aGEOMs.count() > 0) {
-        // one or more GEOM shape selected
-        aSeq->length(aGEOMs.count());
-        QStringList::const_iterator aSubShapesIter = aGEOMs.begin();
-        int iSubSh = 0;
-        for ( ; aSubShapesIter != aGEOMs.end(); aSubShapesIter++, iSubSh++) {
-          QString aSubGeomEntry = (*aSubShapesIter);
-          _PTR(SObject) pSubGeom = SMESH::getStudy()->FindObjectID(aSubGeomEntry.toUtf8().data());
-         
-          if( pSubGeom ) { 
-            SALOMEDS_SObject* sobj = _CAST(SObject,pSubGeom);
-            if( sobj ) {
-              GEOM::GEOM_Object_var aSubGeomVar =
-                GEOM::GEOM_Object::_narrow(sobj->GetObject());
-              if( !aSubGeomVar->_is_nil() ){
-                aSeq[iSubSh] = aSubGeomVar;
-              }
-            }
-          }
+    if ( !myToCreate ) // edition: read hypotheses
+    {
+      if ( pObj )
+      {
+        subMesh  = SMESH::SObjectToInterface< SMESH::SMESH_subMesh >( pObj );
+        myIsMesh = subMesh->_is_nil();
+        myGeom   = SMESH::GetShapeOnMeshOrSubMesh( pObj );
+        myIsInvalidSubMesh = ( !myIsMesh && subMesh->GetId() < 1 );
+        if ( !mesh->_is_nil() && !mesh->HasShapeToMesh() )
+        {
+          myIsOnGeometry = false;
+          myGeom = GEOM::GEOM_Object::_nil();
         }
-      } else {
-        // get geometry by selected sub-mesh
-        QString anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
-        _PTR(SObject) pObj = SMESH::getStudy()->FindObjectID( anObjEntry.toUtf8().data() );
-        GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj );
-        if (!aGeomVar->_is_nil()) {
-          aSeq->length(1);
-          aSeq[0] = aGeomVar;
+        if ( !myGeom->_is_nil() )
+          myGeomEntry = myGeom->GetStudyEntry();
+
+        myDlg->setTitile( myToCreate, myIsMesh );
+        myDlg->setObjectShown( SMESHGUI_MeshDlg::Mesh, !subMesh->_is_nil() );
+        myDlg->setObjectShown( SMESHGUI_MeshDlg::Geom, !myGeom->_is_nil() );
+        myDlg->objectWg( SMESHGUI_MeshDlg::Mesh, SMESHGUI_MeshDlg::Btn )->hide();
+        if ( myIsInvalidSubMesh )
+        {
+          // it is necessary to select a new geometry
+          myDlg->objectWg( SMESHGUI_MeshDlg::Geom, SMESHGUI_MeshDlg::Btn )->show();
+          myDlg->activateObject( SMESHGUI_MeshDlg::Geom );
         }
-      }
-
-      if (aSeq->length() > 0) {
-        shapeDim = -1;
-        for ( CORBA::ULong iss = 0; iss < aSeq->length() && shapeDim < 3; iss++) {
-          GEOM::GEOM_Object_var aGeomVar = aSeq[iss];
-          switch ( aGeomVar->GetShapeType() ) {
-          case GEOM::SOLID:  shapeDim = 3; break;
-          case GEOM::SHELL:
-            // Bug 0016155: EDF PAL 447: If the shape is a Shell, disable 3D tab
-            // {
-            //   TopoDS_Shape aShape;
-            //   bool isClosed = GEOMBase::GetShape(aGeomVar, aShape) && /*aShape.Closed()*/BRep_Tool::IsClosed(aShape);
-            //   shapeDim = qMax(isClosed ? 3 : 2, shapeDim);
-            // }
-            // break;
-          case GEOM::FACE:   shapeDim = qMax(2, shapeDim); break;
-          case GEOM::WIRE:
-          case GEOM::EDGE:   shapeDim = qMax(1, shapeDim); break;
-          case GEOM::VERTEX: shapeDim = qMax(0, shapeDim); break;
-          default:
-            {
-              TopoDS_Shape aShape;
-              if (GEOMBase::GetShape(aGeomVar, aShape))
-              {
-                TopExp_Explorer exp (aShape, TopAbs_SOLID);
-                if (exp.More()) {
-                  shapeDim = 3;
-                }
-                // Bug 0016155: EDF PAL 447: If the shape is a Shell, disable 3D tab
-                // else if ( exp.Init( aShape, TopAbs_SHELL ), exp.More() )
-                // {
-                //   shapeDim = 2;
-                //   for (; exp.More() && shapeDim == 2; exp.Next()) {
-                //     if (/*exp.Current().Closed()*/BRep_Tool::IsClosed(exp.Current()))
-                //       shapeDim = 3;
-                //   }
-                // }
-                else if ( exp.Init( aShape, TopAbs_FACE ), exp.More() )
-                  shapeDim = qMax(2, shapeDim);
-                else if ( exp.Init( aShape, TopAbs_EDGE ), exp.More() )
-                  shapeDim = qMax(1, shapeDim);
-                else if ( exp.Init( aShape, TopAbs_VERTEX ), exp.More() )
-                  shapeDim = qMax(0, shapeDim);
-              }
-            }
-          }
-          if ( shapeDim == 3 )
-            break;
+        else
+        {
+          myDlg->objectWg( SMESHGUI_MeshDlg::Geom, SMESHGUI_MeshDlg::Btn )->hide();
         }
+        myDlg->updateGeometry();
+        myDlg->adjustSize();
+        readMesh();
       }
-      for (int i = SMESH::DIM_3D; i > shapeDim; i--) {
-        // reset algos before disabling tabs (0020138)
-        onAlgoSelected(-1, i);
-      }
-      myDlg->setMaxHypoDim( shapeDim );
-      myMaxShapeDim = shapeDim;
-      myDlg->setHypoSets( SMESH::GetHypothesesSets( shapeDim ));
-
-      if (!myToCreate) // edition: read hypotheses
-      {
-        if (pObj != 0)
+      else
+        myDlg->reset();
+    }
+    else if ( !myIsMesh ) // sub-mesh creation
+    {
+      // if a submesh on the selected shape already exist, pass to submesh edition mode
+      if ( _PTR(SObject) pSubmesh = getSubmeshByGeom() ) {
+        subMesh = SMESH::SObjectToInterface<SMESH::SMESH_subMesh>( pSubmesh );
+        bool editSubmesh = ( !subMesh->_is_nil() &&
+                             SUIT_MessageBox::question( myDlg, tr( "SMESH_WARNING" ),
+                                                        tr( "EDIT_SUBMESH_QUESTION"),
+                                                        SUIT_MessageBox::Yes |
+                                                        SUIT_MessageBox::No,
+                                                        SUIT_MessageBox::No )
+                             == SUIT_MessageBox::Yes );
+        if ( editSubmesh )
         {
-          SMESH::SMESH_subMesh_var submeshVar =
-            SMESH::SMESH_subMesh::_narrow( _CAST( SObject,pObj )->GetObject() );
-          myIsMesh = submeshVar->_is_nil();
-          myIsInvalidSubMesh = ( !myIsMesh && submeshVar->GetId() < 1 );
-          myDlg->setTitile( myToCreate, myIsMesh );
-          myDlg->setObjectShown( SMESHGUI_MeshDlg::Mesh, !submeshVar->_is_nil() );
-          myDlg->setObjectShown( SMESHGUI_MeshDlg::Geom, true );
-          myDlg->objectWg( SMESHGUI_MeshDlg::Mesh, SMESHGUI_MeshDlg::Btn )->hide();
-          if ( myIsInvalidSubMesh )
-          {
-            // it is necessary to select a new geometry
-            myDlg->objectWg( SMESHGUI_MeshDlg::Geom, SMESHGUI_MeshDlg::Btn )->show();
-            myDlg->activateObject( SMESHGUI_MeshDlg::Geom );
-          }
-          else
-          {
-            myDlg->objectWg( SMESHGUI_MeshDlg::Geom, SMESHGUI_MeshDlg::Btn )->hide();
-          }
-          myDlg->updateGeometry();
-          myDlg->adjustSize();
-          readMesh();
+          selectionMgr()->clearFilters();
+          selectObject( pSubmesh );
+          SMESHGUI::GetSMESHGUI()->switchToOperation( SMESHOp::OpEditMeshOrSubMesh );
+          return;
         }
         else
-          myDlg->reset();
-      }
-      else if ( !myIsMesh ) // submesh creation
-      {
-        // if a submesh on the selected shape already exist, pass to submesh edition mode
-        if ( _PTR(SObject) pSubmesh = getSubmeshByGeom() ) {
-          SMESH::SMESH_subMesh_var sm =
-            SMESH::SObjectToInterface<SMESH::SMESH_subMesh>( pSubmesh );
-          bool editSubmesh = ( !sm->_is_nil() &&
-                               SUIT_MessageBox::question( myDlg, tr( "SMESH_WARNING" ),
-                                                          tr( "EDIT_SUBMESH_QUESTION"),
-                                                          SUIT_MessageBox::Yes |
-                                                          SUIT_MessageBox::No,
-                                                          SUIT_MessageBox::No )
-                               == SUIT_MessageBox::Yes );
-          if ( editSubmesh )
-          {
-            selectionMgr()->clearFilters();
-            selectObject( pSubmesh );
-            SMESHGUI::GetSMESHGUI()->switchToOperation( SMESHOp::OpEditMeshOrSubMesh );
-            return;
-          }
-          else
-          {
-            myDlg->selectObject( "", SMESHGUI_MeshDlg::Geom, "" );
-            selectObject( _PTR(SObject)() );
-            selectionDone();
-            return;
-          }
-        }
-        // discard selected mesh if submesh creation not allowed because of
-        // a global algorithm that does not support submeshes
-        if ( char* algoName = isSubmeshIgnored() ) {
-          SUIT_MessageBox::warning( myDlg, tr( "SMESH_ERROR" ),
-                                    tr("SUBMESH_NOT_ALLOWED").arg(algoName));
-          CORBA::string_free( algoName );
-          myDlg->selectObject( "", SMESHGUI_MeshDlg::Mesh, "" );
+        {
+          myDlg->selectObject( "", SMESHGUI_MeshDlg::Geom, "" );
           selectObject( _PTR(SObject)() );
           selectionDone();
           return;
         }
-
-        // enable/disable popup for choice of geom selection way
-        bool enable = false;
-        QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
-        if ( _PTR(SObject) pMesh = SMESH::getStudy()->FindObjectID( aMeshEntry.toUtf8().data() )) {
-          SMESH::SMESH_Mesh_var mesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( pMesh );
-          if ( !mesh->_is_nil() ) {
-            //rnv: issue 21056: EDF 1608 SMESH: Dialog Box "Create Sub Mesh": focus should automatically switch to geometry
-            QString aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
-            _PTR(SObject) pGeom = SMESH::getStudy()->FindObjectID( aGeomEntry.toUtf8().data() );
-            if ( !pGeom || GEOM::GEOM_Object::_narrow( _CAST( SObject,pGeom )->GetObject() )->_is_nil() )
-              myDlg->activateObject(SMESHGUI_MeshDlg::Geom);
-            enable = ( shapeDim > 1 ) && ( mesh->NbEdges() > 0 );
-          }
-        }
-        myDlg->setGeomPopupEnabled( enable );
       }
-    }
-    else { // no geometry defined
+      // discard selected mesh if submesh creation not allowed because of
+      // a global algorithm that does not support submeshes
+      if ( char* algoName = isSubmeshIgnored() ) {
+        SUIT_MessageBox::warning( myDlg, tr( "SMESH_ERROR" ),
+                                  tr("SUBMESH_NOT_ALLOWED").arg(algoName));
+        CORBA::string_free( algoName );
+        myDlg->selectObject( "", SMESHGUI_MeshDlg::Mesh, "" );
+        selectObject( _PTR(SObject)() );
+        selectionDone();
+        return;
+      }
 
-      QStringList hypList;
-      for ( int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++ )
+      // enable/disable popup for choice of geom selection way
+      bool enable = false;
+      QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
+      if ( _PTR(SObject) pMesh = SMESH::getStudy()->FindObjectID( aMeshEntry.toLatin1().data() ))
       {
-        availableHyps( dim, Algo, hypList, myAvailableHypData[dim][Algo]);
-        myDlg->tab( dim )->setAvailableHyps( Algo, hypList );
-        if ( hypList.empty() ) myDlg->disableTab( dim );
-        else                   myDlg->enableTab( dim );
+        mesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( pMesh );
+        if ( !mesh->_is_nil() )
+          enable = /*( shapeDim > 1 ) && */( mesh->NbEdges() > 0 );
       }
-      myMaxShapeDim = -1;
-      //Hide labels and fields (Mesh and Geometry)
-      myDlg->setObjectShown( SMESHGUI_MeshDlg::Mesh, false );
-      myDlg->setObjectShown( SMESHGUI_MeshDlg::Geom, false );
-      myDlg->adjustSize();
-      readMesh();
+      myDlg->setGeomPopupEnabled( enable );
+
+      //rnv: issue 21056: "Create Sub Mesh": focus should automatically switch to geometry
+      if ( pObj && myGeomEntry.isEmpty() )
+        myDlg->activateObject( SMESHGUI_MeshDlg::Geom );
     }
-    int curIndex = myDlg->currentMeshType( );
-    QStringList TypeMeshList;
-    createMeshTypeList( TypeMeshList );
-    setAvailableMeshType( TypeMeshList );
-    curIndex =( curIndex >= TypeMeshList.count() ) ? 0 : curIndex;
-    myDlg->setCurrentMeshType( curIndex );
-    setFilteredAlgoData( myMaxShapeDim, curIndex);
+
+    setFilteredAlgoData();
+
   }
   catch ( const SALOME::SALOME_Exception& S_ex )
   {
@@ -795,7 +681,7 @@ bool SMESHGUI_MeshOp::isValid( QString& theMess ) const
   }*/
 
   // Geom
-  if ( myToCreate )
+  if ( myToCreate || myIsInvalidSubMesh )
   {
     QString aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
     if ( aGeomEntry.isEmpty() )
@@ -850,11 +736,10 @@ bool SMESHGUI_MeshOp::isValid( QString& theMess ) const
 //================================================================================
 /*!
  * \brief check compatibility of the algorithm and another algorithm or hypothesis
-  * \param theAlgoData - algorithm data
-  * \param theHypData - hypothesis data
-  * \param theHypType - hypothesis type
-  * \param theHypTypeName - hypothesis type name, must be provided if 2-nd arg is not algo
-  * \retval bool - check result
+ *  \param theAlgoData - algorithm data
+ *  \param theHypData - hypothesis data
+ *  \param theHypType - hypothesis type
+ *  \retval bool - check result
  */
 //================================================================================
 static bool isCompatible(const HypothesisData* theAlgoData,
@@ -864,41 +749,40 @@ static bool isCompatible(const HypothesisData* theAlgoData,
   if ( !theAlgoData )
     return true;
 
-  if ( theHypType == SMESHGUI_MeshOp::Algo )
+  if ( theHypType == SMESHGUI_MeshOp::Algo ) // compatibility of 2 algos
     return SMESH::IsCompatibleAlgorithm( theAlgoData, theHypData );
 
-  bool isOptional;
+  bool isOptional; // compatibility of algo and hyp
   return ( SMESH::IsAvailableHypothesis( theAlgoData, theHypData->TypeName, isOptional ));
 }
 
 //================================================================================
 /*!
  * \brief check compatibility of the geometry
-  * \param theAlgoData - to select hypos able to be used by this algo
-  * \param theCurrentGeomToSelect - the current name of the selected geometry
-  * \param theGeomVar - currently selected geometry
-  * \retval bool - check result
+ * \param theAlgoData - to select hypos able to be used by this algo
+ * \param theDim - algo dimension
+ * \retval bool - check result
  */
 //================================================================================
 bool SMESHGUI_MeshOp::isCompatibleToGeometry(HypothesisData* theAlgoData,
-                                             QString theCurrentGeomToSelect,
-                                             GEOM::GEOM_Object_var theGeomVar)
+                                             const int       theDim)
 {
-  if ( theGeomVar->_is_nil() )
+  if ( theDim < 1 || myGeom->_is_nil() )
     return true;
 
   bool isApplicable = false;
-  if ( theCurrentGeomToSelect == myLastGeomToSelect && !theCurrentGeomToSelect.isEmpty() ) {
-    THypLabelIsAppMap::const_iterator iter = myHypMapIsApplicable.find( theAlgoData->Label );
-    if ( iter != myHypMapIsApplicable.end() && iter.key() == theAlgoData->Label ) {
-      isApplicable = iter.value();
+  if ( myGeomEntry == myLastGeomEntry && !myGeomEntry.isEmpty() ) {
+    THypLabelIsAppMap::const_iterator lab2isApp = myHypMapIsApplicable.find( theAlgoData->Label );
+    if ( lab2isApp != myHypMapIsApplicable.end() ) {
+      isApplicable = lab2isApp.value();
       return isApplicable;
     }
   }
   bool toCheckIsApplicableToAll = !myIsMesh;
   if ( toCheckIsApplicableToAll )
-    toCheckIsApplicableToAll = ( theGeomVar->GetType() == GEOM_GROUP );
-  isApplicable = SMESH::IsApplicable( theAlgoData->TypeName, theGeomVar, toCheckIsApplicableToAll );
+    toCheckIsApplicableToAll = ( myGeom->GetType() == GEOM_GROUP );
+
+  isApplicable = SMESH::IsApplicable( theAlgoData->TypeName, myGeom, toCheckIsApplicableToAll );
   myHypMapIsApplicable.insert( theAlgoData->Label, isApplicable );
   return isApplicable;
 }
@@ -906,18 +790,59 @@ bool SMESHGUI_MeshOp::isCompatibleToGeometry(HypothesisData* theAlgoData,
 //================================================================================
 /*!
  * \brief check compatibility of the mesh type
 * \param theAlgoData - to select hypos able to be used by this algo
-  * \param theMeshType - type of mesh for filtering algorithms
 * \retval bool - check result
 \param theAlgoData - to select hypos able to be used by this algo
+ *  \param theDim - algo dimension
 \retval bool - check result
  */
 //================================================================================
 bool SMESHGUI_MeshOp::isCompatibleToMeshType(HypothesisData* theAlgoData,
-                                             QString theMeshType)
+                                             const int       theDim)
 {
-  bool isAvailableAlgo = ( theAlgoData->OutputTypes.count() == 0 );
+  if ( theDim < 2 )
+    return true;
+
+  QString elemType;
+  int curMeshType = myDlg->currentMeshType();
+  switch ( curMeshType ) {
+  case MT_ANY:
+    return true;
+
+  case MT_TRIANGULAR:
+    if ( theDim > 2 )
+      return false;
+    elemType = "TRIA";
+    break;
+
+  case MT_QUADRILATERAL:
+    if ( theDim > 2 )
+      return false;
+    elemType = "QUAD";
+    break;
+
+  case MT_TETRAHEDRAL:
+    if ( theDim < 3 )
+      elemType = "TRIA";
+    else
+      elemType = "TETRA";
+    break;
+
+  case MT_HEXAHEDRAL:
+    if ( theDim < 3 )
+      elemType = "QUAD";
+    else
+      elemType = "HEXA";
+    break;
+
+  default:
+    return true;
+  }
+
+  bool isAvailableAlgo = theAlgoData->OutputTypes.isEmpty();
   QStringList::const_iterator inElemType = theAlgoData->OutputTypes.begin();
-  for ( ; inElemType != theAlgoData->OutputTypes.end(); inElemType++ ) {
-    if ( *inElemType == theMeshType ) {
+  for ( ; inElemType != theAlgoData->OutputTypes.end(); inElemType++ )
+  {
+    if ( *inElemType == elemType )
+    {
       isAvailableAlgo = true;
       break;
     }
@@ -927,16 +852,20 @@ bool SMESHGUI_MeshOp::isCompatibleToMeshType(HypothesisData* theAlgoData,
 
 //================================================================================
 /*!
- * \brief Gets available hypotheses or algorithms
 * \param theDim - specifies dimension of returned hypotheses/algorifms
 * \param theHypType - specifies whether algorims or hypotheses or additional ones
 * are retrieved (possible values are in HypType enumeration)
 * \param theHyps - Output list of hypotheses' names
 * \param thePrevAlgoData - to select hypos able to be used by previously algo (optional)
 * \param theNextAlgoData - to select hypos able to be used by next algo (optional)
 * \param theMeshType - type of mesh for filtering algorithms (optional)
+ * \brief Get available hypotheses or algorithms
 \param theDim - specifies dimension of returned hypotheses/algorifms
 \param theHypType - specifies whether algorims or hypotheses or additional ones
*         are retrieved (possible values are in HypType enumeration)
*  \param theHyps - output list of hypotheses' names
 \param thePrevAlgoData - to select hypos able to be used by previously algo (optional)
 \param theNextAlgoData - to select hypos able to be used by next algo (optional)
 \param theMeshType - type of mesh for filtering algorithms (optional)
  *
- * Gets available hypotheses or algorithm in accordance with input parameters
+ * Get available hypotheses or algorithm in accordance with input parameters.
+ * Result (\a theHyps) optionally depends on the following:
+ * - selected algorithm(s)
+ * - selected geometry
+ * - selected mesh type
  */
 //================================================================================
 void SMESHGUI_MeshOp::availableHyps( const int       theDim,
@@ -953,32 +882,16 @@ void SMESHGUI_MeshOp::availableHyps( const int       theDim,
   bool isAux  = ( theHypType >= AddHyp );
   QStringList aHypTypeNameList = SMESH::GetAvailableHypotheses( isAlgo, theDim, isAux, myIsOnGeometry, !myIsMesh );
 
-  GEOM::GEOM_Object_var aGeomVar;
-  QString aCurrentGeomToSelect;
-  if ( !theMeshType.isEmpty() ) {
-    aCurrentGeomToSelect = myDlg->selectedObject( myToCreate ? SMESHGUI_MeshDlg::Geom : SMESHGUI_MeshDlg::Obj );
-    if ( _PTR(SObject) so = SMESH::getStudy()->FindObjectID( aCurrentGeomToSelect.toUtf8().data() )) {
-      aGeomVar = SMESH::GetGeom( so );
-    }
-   if ( aCurrentGeomToSelect != myLastGeomToSelect )
-     myHypMapIsApplicable.clear();
-  }
-
   std::multimap< double, HypothesisData* > sortedHyps;
   QStringList::const_iterator anIter;
   for ( anIter = aHypTypeNameList.begin(); anIter != aHypTypeNameList.end(); ++anIter )
   {
     HypothesisData* aData = SMESH::GetHypothesisData( *anIter );
-    if ( ( isCompatible ( thePrevAlgoData, aData, theHypType ) &&
-           isCompatible ( theNextAlgoData, aData, theHypType ) ) ||
-           ( theMeshType == "ANY" && aData->InputTypes.isEmpty()))
+    if ( isCompatible( thePrevAlgoData, aData, theHypType ) &&
+         isCompatible( theNextAlgoData, aData, theHypType ) &&
+         isCompatibleToGeometry( aData, theDim )            &&
+         isCompatibleToMeshType( aData, theDim ))
     {
-      if ( ( !theMeshType.isEmpty() )  &&
-           ( theDim >= SMESH::DIM_2D ) &&
-           ( ( theMeshType != "ANY" && !isCompatibleToMeshType( aData, theMeshType )) ||
-             !isCompatibleToGeometry( aData, aCurrentGeomToSelect, aGeomVar )))
-        continue;
-
       int  groupID = aData->GroupID;
       int priority = aData->Priority;
       if ( groupID  < 0 || groupID > 9    ) groupID  = 9;
@@ -1006,9 +919,6 @@ void SMESHGUI_MeshOp::availableHyps( const int       theDim,
       theHyps.append( aData->Label );
     }
   }
-
-  if ( !theMeshType.isEmpty() && !aCurrentGeomToSelect.isEmpty() )
-    myLastGeomToSelect = aCurrentGeomToSelect;
 }
 
 //================================================================================
@@ -1016,7 +926,7 @@ void SMESHGUI_MeshOp::availableHyps( const int       theDim,
  * \brief Gets existing hypotheses or algorithms
  *  \param theDim - specifies dimension of returned hypotheses/algorifms
  *  \param theHypType - specifies whether algorims or hypotheses or additional ones
- *  are retrieved (possible values are in HypType enumeration)
+ *         are retrieved (possible values are in HypType enumeration)
  *  \param theFather - start object for finding ( may be component, mesh, or sub-mesh )
  *  \param theHyps - output list of names.
  *  \param theHypVars - output list of variables.
@@ -1124,7 +1034,7 @@ SMESHGUI_MeshOp::getInitParamsHypothesis( const QString& aHypType,
     myDlg->selectedObject( SMESHGUI_MeshDlg::Obj ).count(':') > nbColonsInMeshEntry;
 
   // get mesh and geom object
-  SMESH::SMESH_Mesh_var aMeshVar = SMESH::SMESH_Mesh::_nil();
+  SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_nil();
   GEOM::GEOM_Object_var aGeomVar = GEOM::GEOM_Object::_nil();
 
   QString anEntry;
@@ -1137,7 +1047,7 @@ SMESHGUI_MeshOp::getInitParamsHypothesis( const QString& aHypType,
       CORBA::Object_ptr Obj = _CAST( SObject,pObj )->GetObject();
       if ( myToCreate ) // mesh and geom may be selected
       {
-        aMeshVar = SMESH::SMESH_Mesh::_narrow( Obj );
+        aMesh = SMESH::SMESH_Mesh::_narrow( Obj );
         anEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
         if ( _PTR(SObject) pGeom = SMESH::getStudy()->FindObjectID( anEntry.toUtf8().data() ))
           aGeomVar= GEOM::GEOM_Object::_narrow( _CAST( SObject,pGeom )->GetObject() );
@@ -1146,7 +1056,7 @@ SMESHGUI_MeshOp::getInitParamsHypothesis( const QString& aHypType,
       {
         SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( Obj );
         if ( !sm->_is_nil() ) {
-          aMeshVar = sm->GetFather();
+          aMesh = sm->GetFather();
           aGeomVar = sm->GetSubShape();
         }
       }
@@ -1159,8 +1069,8 @@ SMESHGUI_MeshOp::getInitParamsHypothesis( const QString& aHypType,
       anEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
       if ( _PTR(SObject) pMesh = SMESH::getStudy()->FindObjectID( anEntry.toUtf8().data() ))
       {
-        aMeshVar = SMESH::SMESH_Mesh::_narrow( _CAST( SObject,pMesh )->GetObject() );
-        if ( !aMeshVar->_is_nil() )
+        aMesh = SMESH::SMESH_Mesh::_narrow( _CAST( SObject,pMesh )->GetObject() );
+        if ( !aMesh->_is_nil() )
           aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pMesh );
       }
     }
@@ -1176,13 +1086,13 @@ SMESHGUI_MeshOp::getInitParamsHypothesis( const QString& aHypType,
   SMESH::SMESH_Hypothesis_var hyp =
     SMESHGUI::GetSMESHGen()->GetHypothesisParameterValues( aHypType.toUtf8().data(),
                                                            aServerLib.toUtf8().data(),
-                                                           aMeshVar,
+                                                           aMesh,
                                                            aGeomVar,
                                                            /*byMesh = */isSubMesh);
   if ( hyp->_is_nil() && isSubMesh )
     hyp = SMESHGUI::GetSMESHGen()->GetHypothesisParameterValues( aHypType.toLatin1().data(),
                                                                  aServerLib.toUtf8().data(),
-                                                                 aMeshVar,
+                                                                 aMesh,
                                                                  aGeomVar,
                                                                  /*byMesh = */false);
   return hyp;
@@ -1234,9 +1144,9 @@ void SMESHGUI_MeshOp::initHypCreator( SMESHGUI_GenericHypothesisCreator* theCrea
       SMESH::SMESH_subMesh_var aSubMeshVar =
         SMESH::SMESH_subMesh::_narrow( _CAST( SObject,pObj )->GetObject() );
       if ( !aSubMeshVar->_is_nil() ) {
-        SMESH::SMESH_Mesh_var aMeshVar =  aSubMeshVar->GetFather();
-        if ( !aMeshVar->_is_nil() ) {
-          _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshVar );
+        SMESH::SMESH_Mesh_var aMesh =  aSubMeshVar->GetFather();
+        if ( !aMesh->_is_nil() ) {
+          _PTR(SObject) aMeshSO = SMESH::FindSObject( aMesh );
           GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( aMeshSO );
           if ( !aGeomVar->_is_nil() )
             aMeshEntry = SMESH::toQStr( aGeomVar->GetStudyEntry() );
@@ -1417,9 +1327,7 @@ void SMESHGUI_MeshOp::onHypoCreated( int result )
     for (int i = nbHyp; i < aNewHyps.count(); i++)
       myDlg->tab(myDim)->addHyp(myType, aNewHyps[i]);
   }
-
-  if( result!=2 && myHypoSet )
-    processSet();
+  return;
 }
 
 //================================================================================
@@ -1489,7 +1397,7 @@ void SMESHGUI_MeshOp::onHypoEdited( int result )
   * \param theHypType - hyp type (Algo,MainHyp or AddHyp)
   * \param theIndex - index in the list
   * \retval HypothesisData* - result data, may be 0
- */
 */
 //================================================================================
 HypothesisData* SMESHGUI_MeshOp::hypData( const int theDim,
                                           const int theHypType,
@@ -1504,8 +1412,84 @@ HypothesisData* SMESHGUI_MeshOp::hypData( const int theDim,
 
 //================================================================================
 /*!
+ * \brief Update list of algorithms and hypotheses according to currently selected
+ *        algorithm, geometry and mesh type
+ */
+//================================================================================
+void SMESHGUI_MeshOp::setFilteredAlgoData()
+{
+  // keep current algorithms
+  HypothesisData* curAlgos[ 4 ];
+  for ( int dim = 0; dim <= 3; ++dim )
+    curAlgos[ dim ] = hypData( dim, Algo, currentHyp( dim, Algo ));
+
+  // find out myMaxShapeDim by checking algorithm applicability to geometry
+
+  int curMeshType = myDlg->currentMeshType();
+  myDlg->setCurrentMeshType( MT_ANY );
+  QStringList algosAvailable;
+  // get available algorithms taking into account geometry only
+  if ( myGeom->_is_nil() )
+  {
+    myMaxShapeDim = 3;
+
+    if ( myToCreate ) // readMesh() has done it if !myToCreate
+      for ( int dim = 0; dim <= 3; ++dim )
+        availableHyps( dim, Algo, algosAvailable, myAvailableHypData[ dim ][ Algo ] );
+  }
+  else
+  {
+    if ( myGeomEntry != myLastGeomEntry )
+      myHypMapIsApplicable.clear();
+
+    for ( int dim = 0; dim <= 3; ++dim )
+    {
+      availableHyps( dim, Algo, algosAvailable, myAvailableHypData[ dim ][ Algo ] );
+      if ( algosAvailable.count() )
+        myMaxShapeDim = dim;
+    }
+    if ( !myGeomEntry.isEmpty() )
+      myLastGeomEntry = myGeomEntry;
+  }
+  myDlg->setMaxHypoDim( myMaxShapeDim );
+
+  // set mesh types according to myMaxShapeDim
+  updateMeshTypeList();
+
+  // update available hypo-sets that depend on geometry and mesh type
+  myDlg->setCurrentMeshType( Max( MT_ANY, curMeshType ));
+  updateHypoSets(); // it sets myAvailableHypData by curMeshType
+
+  // restore current algorithms according to changed myAvailableHypData
+  for ( int dim = 0; dim <= 3; ++dim )
+  {
+    int algoIndex = myAvailableHypData[ dim ][ Algo ].indexOf( curAlgos[ dim ]);
+    while ( algosAvailable.count() <= algoIndex )
+      algosAvailable << "";
+    myDlg->tab( dim )->setAvailableHyps( Algo, algosAvailable );
+    setCurrentHyp( dim, Algo, algoIndex );
+    if ( algoIndex < 0 )
+      curAlgos[ dim ] = 0;
+  }
+
+  // find a selected algo, current or of highest dimension
+  int algoDim = myDlg->currentTab();
+  if ( !curAlgos[ algoDim ])
+    for ( algoDim = SMESH::DIM_3D; algoDim >= SMESH::DIM_0D; algoDim-- )
+      if ( curAlgos[ algoDim ] )
+        break;
+  if ( algoDim < SMESH::DIM_0D )
+    algoDim = myMaxShapeDim;
+
+  // set algorithms and hypotheses according to all parameters (mesh type etc)
+  onAlgoSelected( currentHyp( algoDim, Algo ), algoDim );
+}
+
+//================================================================================
+/*!
  * \brief Set available algos and hypos according to the selected algorithm
-  * \param theIndex - algorithm index
+ * \param theIndex - algorithm index
+ * \param theDim - algorithm dimension
  */
 //================================================================================
 void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
@@ -1526,101 +1510,58 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
   algoByDim[ aDim ] = algoData;
 
   QStringList anAvailable;
+  const int algoDim = aDim;
 
-  // enable / disable tabs
-  if ( myIsOnGeometry ) {
-    for (int i = SMESH::DIM_3D; i >= SMESH::DIM_0D; i--) {
-      if ( i > aDim ) {
-        if ( i > myMaxShapeDim ) myDlg->disableTab( i );
-        else                     myDlg->enableTab( i );
-      }
-      else if ( i == aDim ) {
-        continue;
-      }
-      else {//( i < aDim )
-        if ( algoData && algoData->InputTypes.isEmpty() ) {
-          myDlg->disableTab( i );
-          for ( int type = Algo, nbTypes = nbDlgHypTypes(i); type < nbTypes; type++ )
-            setCurrentHyp(i, type, -1);
-        }
-        else {
-          myDlg->enableTab( i );
-        }
-      }
-    }
-  }
-
-  int algoDim = aDim;
-  HypothesisData* a3DAlgo = 0;
-  // 2 loops: backward and forward from algo dimension
-  for ( int forward = 0; forward <= 1; ++forward )
+  // 2 loops: backward and forward from algo dimension (forward == to higher dimension)
+  for ( int forward = 1; forward >= 0; --forward )
   {
-    int dim = algoDim + 1, lastDim = SMESH::DIM_3D, dir = 1;
+    int dim = algoDim, lastDim = SMESH::DIM_3D, dir = 1;
     if ( !forward ) {
       dim = algoDim - 1; lastDim = SMESH::DIM_0D; dir = -1;
     }
-    HypothesisData* prevAlgo = algoData;
-    bool noCompatible = false;
+    //bool noCompatible = false;
     for ( ; dim * dir <= lastDim * dir; dim += dir)
     {
-      if ( !isAccessibleDim( dim ))
-        continue;
-      if ( noCompatible ) { // the selected algo has no compatible ones
-        anAvailable.clear();
+      // if ( noCompatible ) // the selected algo has no compatible ones (like 1D2D3D algo)
+      // {
+      //   anAvailable.clear();
+      //   myDlg->tab( dim )->setAvailableHyps( Algo, anAvailable );
+      //   myAvailableHypData[dim][Algo].clear();
+      //   algoByDim[ dim ] = 0;
+      // }
+      // else
+      {
+        int           algoIndex = currentHyp( dim, Algo );
+        HypothesisData *curAlgo = hypData( dim, Algo, algoIndex );
+
+        // set new available algorithms
+        HypothesisData *prevAlgo = 0;
+        if ( dim != algoDim )
+          for ( int prevDim = dim + 1; prevDim <=3 && !prevAlgo; ++prevDim )
+            prevAlgo = hypData( prevDim, Algo, currentHyp( prevDim, Algo ));
+        availableHyps( dim, Algo, anAvailable, myAvailableHypData[dim][Algo], prevAlgo );
         myDlg->tab( dim )->setAvailableHyps( Algo, anAvailable );
-        myAvailableHypData[dim][Algo].clear();
-        algoByDim[ dim ] = 0;
-        continue;
-      }
-      HypothesisData* nextAlgo = 0;
-      if ( myMaxShapeDim == SMESH::DIM_3D && a3DAlgo && dim == SMESH::DIM_2D ) {
-        nextAlgo = a3DAlgo;
-      }
-      // get currently selected algo
-      int algoIndex = currentHyp( dim, Algo );
-      HypothesisData* curAlgo = hypData( dim, Algo, algoIndex );
-
-      QString anCompareType = currentMeshTypeName(myDlg->currentMeshType());
-      QString anCurrentCompareType = "";
-      if ( dim == SMESH::DIM_3D || anCompareType == "ANY" )
-        anCurrentCompareType = anCompareType;
-      else if ( dim == SMESH::DIM_2D ) {
-        anCurrentCompareType = (anCompareType == "HEXA" || anCompareType == "QUAD") ? "QUAD" : "TRIA";
-        nextAlgo = 0;
-      }
 
-      // set new available algorithms
-      availableHyps( dim, Algo, anAvailable, myAvailableHypData[dim][Algo], prevAlgo, nextAlgo, anCurrentCompareType);
-      HypothesisData* soleCompatible = 0;
-      if ( anAvailable.count() == 1 )
-        soleCompatible = myAvailableHypData[dim][Algo][0];
-      myDlg->tab( dim )->setAvailableHyps( Algo, anAvailable );
-      noCompatible = anAvailable.isEmpty();
-      algoIndex = myAvailableHypData[dim][Algo].indexOf( curAlgo );
-      if ( !isSubmesh && algoIndex < 0 && soleCompatible && !forward && dim == curDim ) {
-        // select the sole compatible algo
-        algoIndex = 0;
+        //noCompatible = ( prevAlgo && !forward && anAvailable.isEmpty() );
+
+        // set current algo
+        algoIndex = myAvailableHypData[dim][Algo].indexOf( curAlgo );
+        setCurrentHyp( dim, Algo, algoIndex, /*updateHyps=*/true );
+
+        algoByDim[ dim ] = hypData( dim, Algo, algoIndex );
       }
-      setCurrentHyp( dim, Algo, algoIndex );
 
-      // remember current algo
-      prevAlgo = algoByDim[ dim ] = hypData( dim, Algo, algoIndex );
+      // activate tabs according to algorithms availability
+      if ( anAvailable.isEmpty() ) myDlg->disableTab( dim );
+      else                         myDlg->enableTab( dim );
 
     } // loop on dims
-
-    if ( myMaxShapeDim == SMESH::DIM_3D && forward && algoDim == SMESH::DIM_1D )
-    {
-      algoDim = SMESH::DIM_3D;
-      forward = -1;
-      a3DAlgo = prevAlgo;
-      continue;
-    }
   } // loops backward and forward
 
 
   // set hypotheses corresponding to the found algorithms
 
-  _PTR(SObject) pObj = SMESH::getStudy()->FindComponent("SMESH");
+  _PTR(SObject) pComp = SMESH::getStudy()->FindComponent("SMESH");
 
   for ( int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++ )
   {
@@ -1646,40 +1587,45 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
       int hypIndex = hypIndexByType[ dlgType ];
 
       SMESH::SMESH_Hypothesis_var curHyp;
+      QString                     curHypType;
+      HypothesisData*             hypData = 0;
       if ( hypIndex >= 0 && hypIndex < myExistingHyps[ dim ][ type ].count() )
+      {
         curHyp = myExistingHyps[ dim ][ type ][ hypIndex ].first;
-
-      if ( !myToCreate && !curAlgo && !curHyp->_is_nil() ) { // edition, algo not selected
+        if ( !curHyp->_is_nil() )
+        {
+          curHypType = SMESH::toQStr( curHyp->GetName() );
+          hypData = SMESH::GetHypothesisData( curHypType );
+        }
+      }
+      if ( !myToCreate && !curAlgo && !curHyp->_is_nil() ) // edition, algo not selected
+      {
         // try to find algo by selected hypothesis in order to keep it selected
         bool algoDeselectedByUser = ( theDim < 0 && aDim == dim );
-        QString curHypType = SMESH::toQStr( curHyp->GetName() );
         if ( !algoDeselectedByUser &&
              myObjHyps[ dim ][ type ].count() > 0 &&
              curHypType == SMESH::toQStr( myObjHyps[ dim ][ type ].first().first->GetName()) )
         {
-          HypothesisData* hypData = SMESH::GetHypothesisData( SMESH::toQStr( curHyp->GetName() ));
-          for (int i = 0; i < myAvailableHypData[ dim ][ Algo ].count(); ++i) {
+          for ( int i = 0; i < myAvailableHypData[ dim ][ Algo ].count(); ++i )
+          {
             curAlgo = myAvailableHypData[ dim ][ Algo ][ i ];
-            if (curAlgo && hypData && isCompatible(curAlgo, hypData, type))
+            if ( curAlgo && hypData && isCompatible( curAlgo, hypData, type ))
               break;
             else
               curAlgo = 0;
           }
         }
       }
+
       // get hyps compatible with curAlgo
       bool defaulHypAvlbl = false;
       if ( curAlgo )
       {
-        // check if a selected hyp is compatible with the curAlgo
-        if ( !curHyp->_is_nil() ) {
-          HypothesisData* hypData = SMESH::GetHypothesisData( SMESH::toQStr( curHyp->GetName() ));
-          if ( !isCompatible( curAlgo, hypData, type ))
-            curHyp = SMESH::SMESH_Hypothesis::_nil();
-        }
-        availableHyps( dim, type, anAvailable, myAvailableHypData[ dim ][ type ], curAlgo);
-        existingHyps( dim, type, pObj, anExisting, myExistingHyps[ dim ][ type ], curAlgo);
-        defaulHypAvlbl = (type == MainHyp && !curAlgo->IsAuxOrNeedHyp );
+        if ( hypData && !isCompatible( curAlgo, hypData, type ))
+          curHyp = SMESH::SMESH_Hypothesis::_nil();
+        availableHyps( dim, type, anAvailable, myAvailableHypData[ dim ][ type ], curAlgo );
+        existingHyps ( dim, type, pComp, anExisting, myExistingHyps[ dim ][ type ], curAlgo );
+        defaulHypAvlbl = ( type == MainHyp && !curAlgo->IsAuxOrNeedHyp );
       }
       // set list of hypotheses
       if ( dlgType <= AddHyp )
@@ -1705,6 +1651,7 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
       setCurrentHyp( dim, dlgType, hypIndex );
     }
   }
+  return;
 }
 
 //================================================================================
@@ -1715,89 +1662,60 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
 //================================================================================
 void SMESHGUI_MeshOp::onHypoSet( const QString& theSetName )
 {
-  myHypoSet = SMESH::GetHypothesesSet(theSetName);
-  if (!myHypoSet)
+  HypothesesSet* aHypoSet = SMESH::GetHypothesesSet(theSetName);
+  if (!aHypoSet)
     return;
 
   // clear all hyps
-  for (int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++) {
+  for (int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++)
+  {
     setCurrentHyp(dim, Algo, -1);
     setCurrentHyp(dim, AddHyp, -1);
     setCurrentHyp(dim, MainHyp, -1);
+    onAlgoSelected( -1, dim );
   }
 
-  myHypoSet->init(true); //algorithms
-  processSet();
-  myHypoSet->init(false); //hypotheses
-  processSet();
-  myHypoSet = 0;
-}
-
-//================================================================================
-/*!
- * \brief One step of hypothesis/algorithm list creation
- *
- * Creates a hypothesis or an algorithm for current item of internal list of names myHypoSet
- */
-//================================================================================
-void SMESHGUI_MeshOp::processSet()
-{
-  myHypoSet->next();
-  if( !myHypoSet->more() )
-    return;
-
-  bool isAlgo = myHypoSet->isAlgo();
-  QString aHypoTypeName = myHypoSet->current();
-  HypothesisData* aHypData = SMESH::GetHypothesisData(aHypoTypeName);
-  if (!aHypData)
-  {
-    processSet();
-    return;
-  }
-
-  int aDim = aHypData->Dim[0];
-  // create or/and set
-  if (isAlgo)
-  {
-    int index = myAvailableHypData[aDim][Algo].indexOf( aHypData );
-    if ( index < 0 )
+  for ( int isAlgo = 1; isAlgo >= 0; --isAlgo )
+    for ( aHypoSet->init( isAlgo ); aHypoSet->more(); aHypoSet->next() )
     {
-      QStringList anAvailable;
-      availableHyps( aDim, Algo, anAvailable, myAvailableHypData[aDim][Algo] );
-      myDlg->tab( aDim )->setAvailableHyps( Algo, anAvailable );
-      index = myAvailableHypData[aDim][Algo].indexOf( aHypData );
-    }
-    setCurrentHyp( aDim, Algo, index );
-    onAlgoSelected( index, aDim );
-    processSet();
-  }
-  else
-  {
-    bool mainHyp = true;
-    QStringList anAvailable;
-    availableHyps( aDim, MainHyp, anAvailable, myAvailableHypData[aDim][MainHyp] );
-    myDlg->tab( aDim )->setAvailableHyps( MainHyp, anAvailable );
-    int index = myAvailableHypData[aDim][MainHyp].indexOf( aHypData );
-    if ( index < 0 )
-    {
-      mainHyp = false;
-      index = myAvailableHypData[aDim][AddHyp].indexOf( aHypData );
+      QString    aHypoTypeName = aHypoSet->current();
+      HypothesisData* aHypData = SMESH::GetHypothesisData( aHypoTypeName );
+      if (!aHypData)
+        continue;
+
+      int aDim = aHypData->Dim[0];
+      // create or/and set
+      if ( isAlgo )
+      {
+        int index = myAvailableHypData[aDim][Algo].indexOf( aHypData );
+        if ( index >= 0 )
+        {
+          setCurrentHyp( aDim, Algo, index );
+          onAlgoSelected( index, aDim );
+        }
+      }
+      else
+      {
+        bool mainHyp = true;
+        int index = myAvailableHypData[aDim][MainHyp].indexOf( aHypData );
+        if ( index < 0 )
+        {
+          mainHyp = false;
+          index = myAvailableHypData[aDim][AddHyp].indexOf( aHypData );
+        }
+        if ( index >= 0 )
+          createHypothesis( aDim, mainHyp ? MainHyp : AddHyp, aHypoTypeName );
+      }
     }
-    if (index >= 0)
-      createHypothesis(aDim, mainHyp ? MainHyp : AddHyp, aHypoTypeName);
-    else
-      processSet();
-  }
+  return;
 }
 
 //================================================================================
 /*!
  * \brief Creates mesh
-  * \param theMess - Output parameter intended for returning error message
-  * \param theEntryList - List of entries of published objects
-  * \retval bool  - TRUE if mesh is created, FALSE otherwise
- *
- * Creates mesh
+ *  \param theMess - Output parameter intended for returning error message
+ *  \param theEntryList - List of entries of published objects
+ *  \retval bool  - TRUE if mesh is created, FALSE otherwise
  */
 //================================================================================
 bool SMESHGUI_MeshOp::createMesh( QString& theMess, QStringList& theEntryList )
@@ -1812,11 +1730,11 @@ bool SMESHGUI_MeshOp::createMesh( QString& theMess, QStringList& theEntryList )
     if ( aSMESHGen->_is_nil() )
       return false;
 
-    SMESH::SMESH_Mesh_var aMeshVar= aSMESHGen->CreateEmptyMesh();
-    if ( aMeshVar->_is_nil() )
+    SMESH::SMESH_Mesh_var aMesh= aSMESHGen->CreateEmptyMesh();
+    if ( aMesh->_is_nil() )
       return false;
 
-    _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshVar.in() );
+    _PTR(SObject) aMeshSO = SMESH::FindSObject( aMesh.in() );
     if ( aMeshSO ) {
       SMESH::SetName( aMeshSO, myDlg->objectText( SMESHGUI_MeshDlg::Obj ) );
       theEntryList.append( aMeshSO->GetID().c_str() );
@@ -1850,10 +1768,10 @@ bool SMESHGUI_MeshOp::createMesh( QString& theMess, QStringList& theEntryList )
     SUIT_OverrideCursor aWaitCursor;
 
     // create mesh
-    SMESH::SMESH_Mesh_var aMeshVar = aSMESHGen->CreateMesh( aGeomVar );
-    if ( aMeshVar->_is_nil() )
+    SMESH::SMESH_Mesh_var aMesh = aSMESHGen->CreateMesh( aGeomVar );
+    if ( aMesh->_is_nil() )
       return false;
-    _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshVar.in() );
+    _PTR(SObject) aMeshSO = SMESH::FindSObject( aMesh.in() );
     if ( aMeshSO ) {
       theEntryList.append( aMeshSO->GetID().c_str() );
       if ( i > 0 ) setDefaultName( namePrefix );
@@ -1874,13 +1792,13 @@ bool SMESHGUI_MeshOp::createMesh( QString& theMess, QStringList& theEntryList )
           SMESH::SMESH_Hypothesis_var aHypVar =
             myExistingHyps[ aDim ][ aHypType ][ aHypIndex ].first;
           if ( !aHypVar->_is_nil() )
-            SMESH::AddHypothesisOnMesh( aMeshVar, aHypVar );
+            SMESH::AddHypothesisOnMesh( aMesh, aHypVar );
         }
       }
       // find or create algorithm
       SMESH::SMESH_Hypothesis_var anAlgoVar = getAlgo( aDim );
       if ( !anAlgoVar->_is_nil() )
-        SMESH::AddHypothesisOnMesh( aMeshVar, anAlgoVar );
+        SMESH::AddHypothesisOnMesh( aMesh, anAlgoVar );
     }
   }
   return true;
@@ -1888,12 +1806,10 @@ bool SMESHGUI_MeshOp::createMesh( QString& theMess, QStringList& theEntryList )
 
 //================================================================================
 /*!
- * \brief Creates sub-mesh
+ * \brief Create sub-mesh
  * \param theMess - Output parameter intended for returning error message
  * \param theEntryList - List of entries of published objects
  * \retval bool  - TRUE if sub-mesh is created, FALSE otherwise
- *
- * Creates sub-mesh
  */
 //================================================================================
 bool SMESHGUI_MeshOp::createSubMesh( QString& theMess, QStringList& theEntryList )
@@ -1905,20 +1821,20 @@ bool SMESHGUI_MeshOp::createSubMesh( QString& theMess, QStringList& theEntryList
     return false;
 
   // get mesh object
-  SMESH::SMESH_Mesh_var aMeshVar =
+  SMESH::SMESH_Mesh_var aMesh =
     SMESH::EntryToInterface<SMESH::SMESH_Mesh>( myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh ));
-  if ( aMeshVar->_is_nil() && myIsInvalidSubMesh )
+  if ( aMesh->_is_nil() && myIsInvalidSubMesh )
   {
     SMESH::SMESH_subMesh_var aSMVar =
       SMESH::EntryToInterface<SMESH::SMESH_subMesh>( myDlg->selectedObject( SMESHGUI_MeshDlg::Obj ));
     if ( !aSMVar->_is_nil() )
-      aMeshVar = aSMVar->GetMesh();
+      aMesh = aSMVar->GetMesh();
   }
-  if ( aMeshVar->_is_nil() )
+  if ( aMesh->_is_nil() )
     return false;
 
   // GEOM shape of the main mesh
-  GEOM::GEOM_Object_var mainGeom = aMeshVar->GetShapeToMesh();
+  GEOM::GEOM_Object_var mainGeom = aMesh->GetShapeToMesh();
 
   // Name for the new sub-mesh
   QString aName = myDlg->objectText(SMESHGUI_MeshDlg::Obj);
@@ -1995,7 +1911,7 @@ bool SMESHGUI_MeshOp::createSubMesh( QString& theMess, QStringList& theEntryList
     aNameOrID = myDlg->selectedObject(SMESHGUI_MeshDlg::Obj);
 
   // create sub-mesh
-  SMESH::SMESH_subMesh_var aSubMeshVar = aMeshVar->GetSubMesh( aGeomVar, aNameOrID.toUtf8().data() );
+  SMESH::SMESH_subMesh_var aSubMeshVar = aMesh->GetSubMesh( aGeomVar, aNameOrID.toUtf8().data() );
   _PTR(SObject) aSubMeshSO = SMESH::FindSObject( aSubMeshVar.in() );
   if ( aSubMeshSO ) {
     SMESH::SetName( aSubMeshSO, aName.toUtf8().data() );
@@ -2030,24 +1946,25 @@ bool SMESHGUI_MeshOp::createSubMesh( QString& theMess, QStringList& theEntryList
   selectObject( _PTR(SObject)() );
   selectionDone();
 
-  checkSubMeshConcurrency( aMeshVar, aSubMeshVar, /*askUser=*/true );
+  checkSubMeshConcurrency( aMesh, aSubMeshVar, /*askUser=*/true );
 
   return true;
 }
 
 //================================================================================
 /*!
- * \brief Gets current hypothesis or algorithms
+ * \brief Return index of current hypothesis or algorithm
   * \param theDim - dimension of hypothesis or algorithm
   * \param theHypType - Type of hypothesis (Algo, MainHyp, AddHyp)
-  * \retval int - current hypothesis or algorithms
- *
- * Gets current hypothesis or algorithms
+  * \retval int - index of current hypothesis or algorithm, -1 if None selected
  */
 //================================================================================
 int SMESHGUI_MeshOp::currentHyp( const int theDim, const int theHypType ) const
 {
-  return myDlg->tab( theDim )->currentHyp( theHypType ) - 1;
+  if ( 0 <= theDim && theDim <= 3 )
+    return myDlg->tab( theDim )->currentHyp( theHypType ) - 1;
+  else
+    return -1;
 }
 
 //================================================================================
@@ -2177,9 +2094,9 @@ SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim )
   QString aHypName = dataList[ aHypIndex ]->TypeName;
 
   // get existing algorithms
-  _PTR(SObject) pObj = SMESH::getStudy()->FindComponent("SMESH");
+  _PTR(SObject) pComp = SMESH::getStudy()->FindComponent("SMESH");
   QStringList tmp;
-  existingHyps( theDim, Algo, pObj, tmp, myExistingHyps[ theDim ][ Algo ]);
+  existingHyps( theDim, Algo, pComp, tmp, myExistingHyps[ theDim ][ Algo ]);
 
   // look for an existing algo of such a type
   THypList& aHypVarList = myExistingHyps[ theDim ][ Algo ];
@@ -2256,25 +2173,25 @@ void SMESHGUI_MeshOp::readMesh()
   if ( !pObj )
     return;
 
-  if (myIsOnGeometry) {
-    // Get name of mesh if current object is sub-mesh
-    SMESH::SMESH_subMesh_var aSubMeshVar =
-      SMESH::SMESH_subMesh::_narrow( _CAST( SObject,pObj )->GetObject() );
-    if ( !aSubMeshVar->_is_nil() )
+  if ( myIsOnGeometry )
+  {
+    // Set name of mesh if current object is sub-mesh
+    SMESH::SMESH_subMesh_var subMesh = SMESH::SObjectToInterface< SMESH::SMESH_subMesh >( pObj );
+    if ( !subMesh->_is_nil() )
     {
-      SMESH::SMESH_Mesh_var aMeshVar =  aSubMeshVar->GetFather();
-      if ( !aMeshVar->_is_nil() )
+      SMESH::SMESH_Mesh_var aMesh =  subMesh->GetFather();
+      if ( !aMesh->_is_nil() )
       {
-        _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshVar );
-        QString aMeshName = name( aMeshSO );
+        _PTR(SObject) aMeshSO = SMESH::FindSObject( aMesh );
+        QString     aMeshName = name( aMeshSO );
         myDlg->setObjectText( SMESHGUI_MeshDlg::Mesh, aMeshName );
       }
-      myHasConcurrentSubBefore = checkSubMeshConcurrency( aMeshVar, aSubMeshVar );
+      myHasConcurrentSubBefore = checkSubMeshConcurrency( aMesh, subMesh );
     }
 
     if ( !myIsInvalidSubMesh )
     {
-      // Get name of geometry object
+      // Set name of geometry object
       CORBA::String_var name = SMESH::GetGeomName( pObj );
       if ( name.in() )
         myDlg->setObjectText( SMESHGUI_MeshDlg::Geom, name.in() );
@@ -2282,20 +2199,22 @@ void SMESHGUI_MeshOp::readMesh()
   }
 
   // Get hypotheses and algorithms assigned to the mesh/sub-mesh
-  QStringList anExisting;
-  const int lastDim = ( myIsOnGeometry ) ? SMESH::DIM_0D : SMESH::DIM_2D;
+  QStringList anExisting, anAvailable;
   bool algoFound = false;
-  for ( int dim = SMESH::DIM_3D; dim >= lastDim; --dim )
+  const int dim1st = ( myIsOnGeometry ) ? SMESH::DIM_0D : SMESH::DIM_2D;
+  for ( int dim = dim1st; dim <= SMESH::DIM_3D; ++dim )
   {
     // get algorithm
     existingHyps( dim, Algo, pObj, anExisting, myObjHyps[ dim ][ Algo ] );
     // find algo index among available ones
     int aHypIndex = -1;
+    anAvailable.clear();
     if ( myObjHyps[ dim ][ Algo ].count() > 0 )
     {
-      SMESH::SMESH_Hypothesis_var aVar = myObjHyps[ dim ][ Algo ].first().first;
-      HypothesisData* algoData = SMESH::GetHypothesisData( SMESH::toQStr( aVar->GetName() ));
-      aHypIndex = myAvailableHypData[ dim ][ Algo ].indexOf ( algoData );
+      SMESH::SMESH_Hypothesis_var hyp = myObjHyps[ dim ][ Algo ].first().first;
+      HypothesisData* algoData = SMESH::GetHypothesisData( SMESH::toQStr( hyp->GetName() ));
+      availableHyps( dim, Algo, anAvailable, myAvailableHypData[ dim ][ Algo ] );
+      aHypIndex = myAvailableHypData[ dim ][ Algo ].indexOf( algoData );
       //       if ( aHypIndex < 0 && algoData ) {
       //         // assigned algo is incompatible with other algorithms
       //         myAvailableHypData[ dim ][ Algo ].push_back( algoData );
@@ -2303,6 +2222,7 @@ void SMESHGUI_MeshOp::readMesh()
       //       }
       algoFound = ( aHypIndex > -1 );
     }
+    myDlg->tab( dim )->setAvailableHyps( Algo, anAvailable );
     setCurrentHyp( dim, Algo, aHypIndex );
     // set existing and available hypothesis according to the selected algo
     if ( aHypIndex > -1 || !algoFound )
@@ -2311,7 +2231,7 @@ void SMESHGUI_MeshOp::readMesh()
 
   // get hypotheses
   bool hypWithoutAlgo = false;
-  for ( int dim = SMESH::DIM_3D; dim >= lastDim; --dim )
+  for ( int dim = dim1st; dim <= SMESH::DIM_3D; ++dim )
   {
     for ( int hypType = MainHyp; hypType <= AddHyp; hypType++ )
     {
@@ -2344,7 +2264,7 @@ void SMESHGUI_MeshOp::readMesh()
   }
   // make available other hyps of same type as one without algo
   if ( hypWithoutAlgo )
-    onAlgoSelected( currentHyp( 0, Algo ), 0 );
+    onAlgoSelected( currentHyp( /*dim=*/0, Algo ), /*dim=*/0 );
 }
 
 //================================================================================
@@ -2451,11 +2371,11 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess )
 
   SALOMEDS_SObject* aSObject = _CAST(SObject, pObj);
   CORBA::Object_var anObject = aSObject->GetObject();
-  SMESH::SMESH_Mesh_var       aMeshVar = SMESH::SMESH_Mesh::_narrow( anObject );
+  SMESH::SMESH_Mesh_var          aMesh = SMESH::SMESH_Mesh::_narrow( anObject );
   SMESH::SMESH_subMesh_var aSubMeshVar = SMESH::SMESH_subMesh::_narrow( anObject );
-  bool isMesh = !aMeshVar->_is_nil();
+  bool isMesh = !aMesh->_is_nil();
   if ( !isMesh && !aSubMeshVar->_is_nil() )
-    aMeshVar = aSubMeshVar->GetFather();
+    aMesh = aSubMeshVar->GetFather();
 
   // Assign new algorithms and hypotheses
   for ( int dim = aDim; dim <= SMESH::DIM_3D; dim++ )
@@ -2470,7 +2390,7 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess )
          myObjHyps[ dim ][ Algo ].count() == 0 ) // no algo assigned
     {
       if ( isMesh )
-        SMESH::AddHypothesisOnMesh( aMeshVar, anAlgoVar );
+        SMESH::AddHypothesisOnMesh( aMesh, anAlgoVar );
       else if ( !aSubMeshVar->_is_nil() )
         SMESH::AddHypothesisOnSubMesh( aSubMeshVar, anAlgoVar );
 
@@ -2503,7 +2423,7 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess )
         if ( !isAssigned )
         {
           if ( isMesh )
-            SMESH::AddHypothesisOnMesh (aMeshVar, hyp );
+            SMESH::AddHypothesisOnMesh (aMesh, hyp );
           else if ( !aSubMeshVar->_is_nil() )
             SMESH::AddHypothesisOnSubMesh ( aSubMeshVar, hyp );
         }
@@ -2515,7 +2435,7 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess )
   }
 
   myHasConcurrentSubBefore =
-    checkSubMeshConcurrency( aMeshVar, aSubMeshVar, /*askUser=*/!myHasConcurrentSubBefore );
+    checkSubMeshConcurrency( aMesh, aSubMeshVar, /*askUser=*/!myHasConcurrentSubBefore );
 
   return true;
 }
@@ -2605,13 +2525,13 @@ void SMESHGUI_MeshOp::onGeomSelectionByMesh( bool theByMesh )
     // set mesh object to SMESHGUI_ShapeByMeshOp and start it
     QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
     if ( _PTR(SObject) pMesh = SMESH::getStudy()->FindObjectID( aMeshEntry.toUtf8().data() )) {
-      SMESH::SMESH_Mesh_var aMeshVar =
+      SMESH::SMESH_Mesh_var aMesh =
         SMESH::SMESH_Mesh::_narrow( _CAST( SObject,pMesh )->GetObject() );
-      if ( !aMeshVar->_is_nil() ) {
+      if ( !aMesh->_is_nil() ) {
         myDlg->hide(); // stop processing selection
         myShapeByMeshOp->setModule( getSMESHGUI() );
         myShapeByMeshOp->setStudy( 0 ); // it's really necessary
-        myShapeByMeshOp->SetMesh( aMeshVar );
+        myShapeByMeshOp->SetMesh( aMesh );
         myShapeByMeshOp->start();
       }
     }
@@ -2673,185 +2593,55 @@ void SMESHGUI_MeshOp::selectObject( _PTR(SObject) theSObj ) const
 }
 //================================================================================
 /*!
- * \brief Create available list types of mesh
-  * \param theTypeMesh - Output list of available types of mesh
+ * \brief Update available list of mesh types
  */
 //================================================================================
-void SMESHGUI_MeshOp::createMeshTypeList( QStringList& theTypeMesh)
+void SMESHGUI_MeshOp::updateMeshTypeList()
 {
-  theTypeMesh.clear();
-  theTypeMesh.append( tr( "MT_ANY" ) );
+  QStringList meshTypes;
+  meshTypes.append( tr( "MT_ANY" ) );
   if ( myMaxShapeDim >= 2 || myMaxShapeDim == -1 )
   {
-    theTypeMesh.append( tr( "MT_TRIANGULAR" ) );
-    theTypeMesh.append( tr( "MT_QUADRILATERAL" ) );
+    meshTypes.append( tr( "MT_TRIANGULAR" ) );
+    meshTypes.append( tr( "MT_QUADRILATERAL" ) );
   }
   if ( myMaxShapeDim == 3 || myMaxShapeDim == -1 )
   {
-    theTypeMesh.append( tr( "MT_TETRAHEDRAL" ) );
-    theTypeMesh.append( tr( "MT_HEXAHEDRAL" ) );
+    meshTypes.append( tr( "MT_TETRAHEDRAL" ) );
+    meshTypes.append( tr( "MT_HEXAHEDRAL" ) );
   }
 
-}
-//================================================================================
-/*!
- * \brief Set available types of mesh
-  * \param theTypeMesh - List of available types of mesh
- */
-//================================================================================
-void SMESHGUI_MeshOp::setAvailableMeshType( const QStringList& theTypeMesh )
-{
-  myDlg->setAvailableMeshType( theTypeMesh );
+  myDlg->setAvailableMeshType( meshTypes );
 }
 
 //================================================================================
 /*!
- * \brief SLOT. Is called when the user select type of mesh
-  * \param theTabIndex - Index of current active tab
-  * \param theIndex - Index of current type of mesh
+ * \brief Update available list of hypothesis sets
  */
 //================================================================================
-void SMESHGUI_MeshOp::onAlgoSetByMeshType( const int theTabIndex, const int theIndex )
+void SMESHGUI_MeshOp::updateHypoSets()
 {
-  setFilteredAlgoData( theTabIndex, theIndex);
-}
+  // get available algorithms taking into account geometry and mesh type
+  QStringList algosAvailable;
+  if ( myDlg->currentMeshType() != MT_ANY )
+    for ( int dim = 0; dim <= 3; ++dim )
+      availableHyps( dim, Algo, algosAvailable, myAvailableHypData[ dim ][ Algo ] );
 
-//================================================================================
-/*!
- * \brief Set a filtered list of available algorithms by mesh type
-  * \param theTabIndex - Index of current active tab
-  * \param theIndex - Index of current type of mesh
- */
-//================================================================================
-void SMESHGUI_MeshOp::setFilteredAlgoData( const int theTabIndex, const int theIndex )
-{
-  QStringList anAvailableAlgs;
-  QString anCompareType = currentMeshTypeName( theIndex );
-  int anCurrentAvailableAlgo = -1;
-  bool isNone = true;
-  int aDim = SMESH::DIM_3D;
-  if ( theIndex == MT_TRIANGULAR || theIndex == MT_QUADRILATERAL)
-    aDim = SMESH::DIM_2D;
-  if ( anCompareType == "ANY" )
-  {
-    bool isReqDisBound = false;
-    int aReqDim = SMESH::DIM_3D;
-    for ( int dim = SMESH::DIM_3D; dim >= SMESH::DIM_2D; dim-- )
-    {
-      anCurrentAvailableAlgo = -1;
-      isNone = currentHyp( dim, Algo ) < 0;
-      //return current algo in current tab and set new algorithm list
-      HypothesisData* algoCur = 0;
-      if ( !isNone && !myAvailableHypData[dim][Algo].empty() ) {
-        algoCur = myAvailableHypData[dim][Algo].at( currentHyp( dim, Algo ) );
-      }
-      HypothesisData* prevAlgo = 0;
-      HypothesisData* nextAlgo = 0;
-      if ( dim == SMESH::DIM_2D ) {
-        prevAlgo = hypData( SMESH::DIM_1D, Algo, currentHyp( SMESH::DIM_1D, Algo ) );
-        if ( aDim == SMESH::DIM_3D )
-          nextAlgo = hypData( SMESH::DIM_3D, Algo, currentHyp( SMESH::DIM_3D, Algo ) );
-      }
-      // retrieves a list of available algorithms from resources
-      availableHyps( dim, Algo, anAvailableAlgs, myAvailableHypData[dim][Algo], prevAlgo, nextAlgo, anCompareType);
-      anCurrentAvailableAlgo = myAvailableHypData[dim][Algo].indexOf( algoCur );
-      myDlg->tab( dim )->setAvailableHyps( Algo, anAvailableAlgs );
-      setCurrentHyp( dim, Algo, anCurrentAvailableAlgo );
-      if ( anCurrentAvailableAlgo > -1 )
-        isReqDisBound = algoCur->InputTypes.isEmpty();
-      if ( isReqDisBound ) {
-        aReqDim = dim;
-        break;
-      }
-    }
-    if ( !myIsOnGeometry )
-      for ( int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++ ) {
-        bool disable = myAvailableHypData[i][Algo].isEmpty();
-        if ( disable ) myDlg->disableTab( i );
-        else           myDlg->enableTab( i );
-      }
-    else
-      for ( int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++ ) {
-        if ( i > myMaxShapeDim || ( isReqDisBound && i < aReqDim ) ) myDlg->disableTab( i );
-        else                                                         myDlg->enableTab( i );
-      }
-    myDlg->setCurrentTab( theTabIndex );
-  }
-  else
-  {
-    HypothesisData* anCurrentAlgo = 0;
-    bool isReqDisBound = true;
-    QString anCurrentCompareType = anCompareType;
-    isNone = currentHyp( aDim, Algo ) < 0;
-    if ( !isNone && !myAvailableHypData[aDim][Algo].empty() )
-      isReqDisBound = myAvailableHypData[aDim][Algo].at( currentHyp( aDim, Algo ) )->InputTypes.isEmpty();
-    for ( int dim = aDim; dim >= SMESH::DIM_2D; dim-- )
-    {
-      bool isNoneAlg = currentHyp( dim, Algo ) < 0;
-      anCurrentAvailableAlgo = -1;
-      HypothesisData* prevAlgo = 0;
-      HypothesisData* nextAlgo = 0;
-      if ( dim == SMESH::DIM_2D ) {
-        prevAlgo = hypData( SMESH::DIM_1D, Algo, currentHyp( SMESH::DIM_1D, Algo ) );
-        if ( aDim == SMESH::DIM_3D )
-          nextAlgo = hypData( SMESH::DIM_3D, Algo, currentHyp( SMESH::DIM_3D, Algo ) );
-      }
-      // finding algorithm which is selected
-      if ( !isNoneAlg ) {
-        anCurrentAlgo = myAvailableHypData[dim][Algo].at( currentHyp( dim, Algo ) );
-      }
-      // retrieves a list of available algorithms from resources
-      availableHyps( dim, Algo, anAvailableAlgs, myAvailableHypData[dim][Algo], prevAlgo, nextAlgo, anCurrentCompareType );
-      // finding and adding algorithm depending on the type mesh
-      anCurrentAvailableAlgo = myAvailableHypData[dim][Algo].indexOf( anCurrentAlgo );
-      //set new algorithm list and select the current algorithm
-      myDlg->tab( dim )->setAvailableHyps( Algo, anAvailableAlgs );
-      anCurrentCompareType = ( anCompareType == "HEXA" || anCompareType == "QUAD" ) ? "QUAD" : "TRIA";
-      setCurrentHyp( dim, Algo, anCurrentAvailableAlgo, /*updateHyps=*/true );
-    }
-
-    for ( int i = myMaxShapeDim; i >= SMESH::DIM_0D; i-- ) {
-      bool isNoneAlg = currentHyp( i, Algo ) < 0;
-      if ( !isNoneAlg )
-        isReqDisBound = myAvailableHypData[i][Algo].at( currentHyp( i, Algo ) )->InputTypes.isEmpty();
-      else
-        isReqDisBound = true;
-      if ( isReqDisBound && !isNoneAlg && i <= aDim) {
-        for (int j = myMaxShapeDim; j >= SMESH::DIM_0D; j--) {
-          if ( currentHyp( j, Algo ) < 0 ) {
-            myDlg->disableTab( j );
-            setCurrentHyp( j , Algo, -1, /*updateHyps=*/true );
-          }
-        }
-        break;
-      }
-      else {
-        myDlg->enableTab( i );
-      }
-    }
-    if ( aDim == SMESH::DIM_2D) {
-      setCurrentHyp( SMESH::DIM_3D, Algo, -1, /*updateHyps=*/true );
-      myDlg->disableTab( SMESH::DIM_3D );
-    }
-
-    int currentTab = ( theTabIndex <= aDim ) ? theTabIndex : aDim;
-    myDlg->setCurrentTab( currentTab );
-  }
   THypDataList anAvailableAlgsData;
-  QStringList aHypothesesSetsList = SMESH::GetHypothesesSets( aDim );
+  QStringList aHypothesesSetsList = SMESH::GetHypothesesSets( myMaxShapeDim );
   QStringList aFilteredHypothesesSetsList;
-  aFilteredHypothesesSetsList.clear();
   QStringList::const_iterator inHypoSetName = aHypothesesSetsList.begin();
-  for ( ; inHypoSetName != aHypothesesSetsList.end(); ++inHypoSetName ) {
+  for ( ; inHypoSetName != aHypothesesSetsList.end(); ++inHypoSetName )
+  {
     HypothesesSet* currentHypoSet = SMESH::GetHypothesesSet( *inHypoSetName );
     bool isAvailable = false;
-    currentHypoSet->init( true );
-    while ( currentHypoSet->next(), currentHypoSet->more() ) {
+    for ( currentHypoSet->init( true ); currentHypoSet->more(); currentHypoSet->next() )
+    {
       isAvailable = false;
       if ( HypothesisData* algoDataIn = SMESH::GetHypothesisData( currentHypoSet->current() )) {
         for (int i = SMESH::DIM_0D; i <= myMaxShapeDim; i++) {
-          int anCurrentAvailableAlgo = myAvailableHypData[i][Algo].indexOf( algoDataIn );
-          if ( anCurrentAvailableAlgo > -1 ) {
+          int aCurrentAvailableAlgo = myAvailableHypData[i][Algo].indexOf( algoDataIn );
+          if ( aCurrentAvailableAlgo > -1 ) {
             isAvailable = true;
             break;
           }
@@ -2868,32 +2658,12 @@ void SMESHGUI_MeshOp::setFilteredAlgoData( const int theTabIndex, const int theI
 
 //================================================================================
 /*!
- * \brief Get current name types of mesh
-  * \param theIndex - current index types of mesh
-  * \retval QString - result
+ * \brief SLOT. Is called when the user select type of mesh
+ * \param theTabIndex - Index of current active tab
+ * \param theIndex - Index of current type of mesh
  */
 //================================================================================
-QString SMESHGUI_MeshOp::currentMeshTypeName( const int theIndex ) const
+void SMESHGUI_MeshOp::onAlgoSetByMeshType( const int theTabIndex, const int theIndex )
 {
-  QString aMeshType = "";
-  switch ( theIndex ) {
-  case MT_ANY:
-    aMeshType = "ANY";
-    break;
-  case MT_TRIANGULAR:
-    aMeshType = "TRIA";
-    break;
-  case MT_QUADRILATERAL:
-    aMeshType = "QUAD";
-    break;
-  case MT_TETRAHEDRAL:
-    aMeshType = "TETRA";
-    break;
-  case MT_HEXAHEDRAL:
-    aMeshType = "HEXA";
-    break;
-  default:;
-  }
-  return aMeshType;
+  setFilteredAlgoData();
 }
-
index 9f35b7f..d93e4a1 100644 (file)
 
 #include "SMESHGUI_SelectionOp.h"
 
+// IDL includes
+#include <SALOMEconfig.h>
+#include CORBA_CLIENT_HEADER(SMESH_Gen)
+#include CORBA_CLIENT_HEADER(GEOM_Gen)
+
 class HypothesesSet;
 class SMESHGUI_MeshDlg;
 class SMESHGUI_ShapeByMeshOp;
@@ -82,7 +87,6 @@ protected slots:
   void                           onPublishShapeByMeshDlg( SUIT_Operation* );
   void                           onCloseShapeByMeshDlg( SUIT_Operation* );
   void                           onAlgoSelected( const int, const int = -1 );
-  void                           processSet();
   void                           onHypoCreated( int );
   void                           onHypoEdited( int );
   void                           onAlgoSetByMeshType( const int, const int );
@@ -92,11 +96,8 @@ private:
   typedef QMap<QString, bool>    THypLabelIsAppMap; // typedef: map of hypothesis is applicable
 
   bool                           isValid( QString& ) const;
-  bool                           isCompatibleToGeometry( HypothesisData* ,
-                                                         QString,
-                                                         GEOM::GEOM_Object_var);
-  bool                           isCompatibleToMeshType( HypothesisData* ,
-                                                         QString);
+  bool                           isCompatibleToGeometry( HypothesisData* , const int);
+  bool                           isCompatibleToMeshType( HypothesisData* , const int);
   void                           availableHyps( const int, 
                                                 const int,
                                                 QStringList&,
@@ -142,10 +143,9 @@ private:
   char*                          isSubmeshIgnored() const;
   _PTR(SObject)                  getSubmeshByGeom() const;
   void                           selectObject( _PTR(SObject) ) const;
-  void                           createMeshTypeList( QStringList& );
-  void                           setAvailableMeshType( const QStringList& );
-  void                           setFilteredAlgoData( const int, const int );
-  QString                        currentMeshTypeName( const int ) const;
+  void                           updateMeshTypeList();
+  void                           updateHypoSets();
+  void                           setFilteredAlgoData();
 
 private:
 
@@ -159,15 +159,17 @@ private:
   // The geometry of "invalid sub-mesh" is not a sub-shape of the main shape;
   // it is created for the case where a valid sub-shape not found by CopyMeshWithGeom()
 
+  QString                        myGeomEntry;
+  GEOM::GEOM_Object_var          myGeom;
+
   TDim2Type2HypList              myExistingHyps; //!< all hypothesis of SMESH module
   TDim2Type2HypList              myObjHyps;      //!< hypothesis assigned to the current
                                                  //   edited mesh/sub-mesh
   // hypdata corresponding to hypotheses present in myDlg
   THypDataList                   myAvailableHypData[4][NbHypTypes];
-  QString                        myLastGeomToSelect;
+  QString                        myLastGeomEntry;
   THypLabelIsAppMap              myHypMapIsApplicable;
   bool                           myIgnoreAlgoSelection;
-  HypothesesSet*                 myHypoSet;
   int                            myDim, myType, myMaxShapeDim;
 
   QString                        myObjectToSelect;
index 7cc9294..725431f 100644 (file)
@@ -8222,7 +8222,7 @@ as they are of improper type:
         <translation>
 Some sub-shapes not found in the new geometry. They are listed 
 below along with dependent mesh objects that are marked with
-with red in the Object Browser.</translation>
+red in the Object Browser.</translation>
     </message>
 </context>
 <context>
index 9692a8b..0adf75e 100644 (file)
@@ -61,6 +61,7 @@ SET(SMESHUtils_HEADERS
   SMESH_MAT2d.hxx
   SMESH_ControlPnt.hxx
   SMESH_Delaunay.hxx
+  SMESH_Indexer.hxx
   )
 
 # --- sources ---
index 8b1f252..e2a4a99 100644 (file)
@@ -276,12 +276,12 @@ const BRepMesh_Triangle* SMESH_Delaunay::GetTriangleNear( int iBndNode )
   int nodeIDs[3];
   int nbNbNodes = _bndNodes.size();
 #if OCC_VERSION_LARGE <= 0x07030000
-  const BRepMesh::ListOfInteger & linkIds = _triaDS->LinksConnectedTo( iBndNode + 1 );
-  BRepMesh::ListOfInteger::const_iterator iLink = linkIds.cbegin();
+  typedef BRepMesh::ListOfInteger TLinkList;
 #else
-  const IMeshData::ListOfInteger & linkIds = _triaDS->LinksConnectedTo( iBndNode + 1 );
-  IMeshData::ListOfInteger::const_iterator iLink = linkIds.cbegin();
+  typedef IMeshData::ListOfInteger TLinkList;
 #endif
+  const TLinkList &       linkIds = _triaDS->LinksConnectedTo( iBndNode + 1 );
+  TLinkList::const_iterator iLink = linkIds.cbegin();
   for ( ; iLink != linkIds.cend(); ++iLink )
   {
     const BRepMesh_PairOfIndex & triaIds = _triaDS->ElementsConnectedTo( *iLink );
@@ -363,7 +363,7 @@ void SMESH_Delaunay::ToPython() const
   text << "import salome, SMESH\n";
   text << "salome.salome_init()\n";
   text << "from salome.smesh import smeshBuilder\n";
-  text << "smesh = smeshBuilder.New(salome.myStudy)\n";
+  text << "smesh = smeshBuilder.New()\n";
   text << "mesh=smesh.Mesh()\n";
   const char* endl = "\n";
 
@@ -388,5 +388,5 @@ void SMESH_Delaunay::ToPython() const
   file.remove();
   file.openForWriting();
   file.write( text.c_str(), text.size() );
-  cout << "execfile( '" << fileName << "')" << endl;
+  cout << "exec(open('" << fileName << "', 'rb').read())";
 }
diff --git a/src/SMESHUtils/SMESH_Indexer.hxx b/src/SMESHUtils/SMESH_Indexer.hxx
new file mode 100644 (file)
index 0000000..ff5628b
--- /dev/null
@@ -0,0 +1,153 @@
+// Copyright (C) 2007-2019  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
+//
+// 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, 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
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File      : SMESH_Indexer.hxx
+// Created   : Tue May 21 18:24:01 2019
+// Author    : Edward AGAPOV (eap)
+
+
+#ifndef __SMESH_Indexer_HXX__
+#define __SMESH_Indexer_HXX__
+
+//================================================================================
+/*!
+ * \brief Converter of a pair of indices to a sole index, useful to make
+ *        1D array behave as 2D one
+ */
+struct SMESH_Indexer
+{
+  size_t _xSize, _ySize;
+
+  //! Initialize with size in two directions
+  SMESH_Indexer( size_t xSize=0, size_t ySize=0 ): _xSize(xSize), _ySize(ySize) {}
+
+  //! set size
+  void set(size_t xSize, size_t ySize ) { _xSize = xSize, _ySize = ySize; }
+
+  //! \return size of 1D array
+  size_t size() const { return _xSize * _ySize; }
+
+  // \return 1D index by two indices
+  size_t operator()(size_t x, size_t y) const { return y * _xSize + x; }
+};
+
+//================================================================================
+/*!
+ * \brief Converter of a triple of indices to a sole index, useful to make
+ *        1D array behave as 3D one
+ */
+struct SMESH_Indexer3D
+{
+  size_t _xSize, _ySize, _zSize;
+
+  //! Initialize with size in two directions
+  SMESH_Indexer3D( size_t xSize=0, size_t ySize=0, size_t zSize=0 ):
+    _xSize(xSize), _ySize(ySize), _zSize(zSize) {}
+
+  //! set size
+  void set(size_t xSize, size_t ySize, size_t zSize )
+  { _xSize = xSize, _ySize = ySize, _zSize = zSize; }
+
+  //! \return size of 1D array
+  size_t size() const { return _xSize * _ySize * _zSize; }
+
+  // \return 1D index by three indices
+  size_t operator()(size_t x, size_t y, size_t z) const { return z*_xSize*_ySize +  y*_xSize + x; }
+};
+
+//================================================================================
+/*!
+ * \brief Oriented converter of a pair of integers to a sole index
+ *
+ * Allows virtual transformation of an 1D array viewed as 2D one.
+ * Possible transformations are inverse in one or two directions and exchange of
+ * the directions. Any combination of these transformations is allowed.
+ *
+ * The following code picks up a transformation such that two known array items
+ * appear in a desired positions:
+ * \code
+ * for ( int ori = 0; ori < SMESH_OrientedIndexer::MAX_ORI+1; ++ori )
+ * {
+ *   SMESH_OrientedIndexer oriIndex( index, ori );
+ *   if ( item1 == array[ oriIndex( i1, j1 ) ] &&
+ *        item2 == array[ oriIndex( i2, j2 ) ])
+ *   {
+ *     // needed transformation found
+ *   }
+ * }
+ * \endcode
+ */
+class SMESH_OrientedIndexer : public SMESH_Indexer
+{
+  typedef SMESH_Indexer TFather;
+public:
+  enum OriFlags //!< transformation types
+    {
+      REV_X = 1, REV_Y = 2, SWAP_XY = 4, MAX_ORI = REV_X|REV_Y|SWAP_XY
+    };
+
+  SMESH_OrientedIndexer( const SMESH_Indexer& indexer, const int oriFlags ):
+    TFather( indexer._xSize, indexer._ySize ),
+    _xRevFun( (oriFlags & REV_X) ? & reverse : & lazy ),
+    _yRevFun( (oriFlags & REV_Y) ? & reverse : & lazy ),
+    _swapFun( (oriFlags & SWAP_XY ) ? & swap : & lazy ),
+    _xSizeOriented( indexer._xSize ),
+    _ySizeOriented( indexer._ySize )
+  {
+    (*_swapFun)( _xSizeOriented, _ySizeOriented );
+  }
+
+  //!< Return index by XY
+  size_t operator()(size_t x, size_t y) const
+  {
+    (*_swapFun)( x, y );
+    (*_xRevFun)( x, const_cast< size_t& >( _xSize ));
+    (*_yRevFun)( y, const_cast< size_t& >( _ySize ));
+    return TFather::operator()( x, y );
+  }
+
+  //!< Return index for a corner
+  size_t corner(bool xMax, bool yMax) const
+  {
+    size_t x = xMax, y = yMax, size = 2;
+    (*_swapFun)( x, y );
+    (*_xRevFun)( x, size );
+    (*_yRevFun)( y, size );
+    return TFather::operator()( x ? _xSize-1 : 0,
+                                y ? _ySize-1 : 0 );
+  }
+  size_t xSize() const { return _xSizeOriented; }
+  size_t ySize() const { return _ySizeOriented; }
+
+private:
+
+  typedef void (*TFun)(size_t& x, size_t& y);
+  TFun _xRevFun, _yRevFun, _swapFun;
+
+  size_t _xSizeOriented, _ySizeOriented;
+
+  static void lazy   (size_t&  , size_t& ) {}
+  static void reverse(size_t& x, size_t& size) { x = size - x - 1; }
+  static void swap   (size_t& x, size_t& y) { std::swap( x, y ); }
+};
+
+
+#endif
index 7b4e4b4..294a8ae 100644 (file)
@@ -76,6 +76,7 @@ namespace SMESHUtils
     TVECTOR v2( vec );
     vec.swap( v2 );
   }
+
   /*!
    * \brief Auto pointer
    */
@@ -91,6 +92,7 @@ namespace SMESHUtils
   private:
     Deleter( const Deleter& );
   };
+
   /*!
    * \brief Auto pointer to array
    */
@@ -104,6 +106,9 @@ namespace SMESHUtils
     ArrayDeleter( const ArrayDeleter& );
   };
 
+  /*!
+   * \return SMDS_ElemIteratorPtr on an std container of SMDS_MeshElement's
+   */
   template < class ELEM_SET >
   SMDS_ElemIteratorPtr elemSetIterator( const ELEM_SET& elements )
   {
@@ -111,6 +116,24 @@ namespace SMESHUtils
       < SMDS_pElement, typename ELEM_SET::const_iterator> TSetIterator;
     return boost::make_shared< TSetIterator >( elements.begin(), elements.end() );
   }
+
+  /*!
+   * \brief Increment enum value
+   */
+  template < typename ENUM >
+  void Increment( ENUM& v, int delta=1 )
+  {
+    v = ENUM( int(v)+delta );
+  }
+
+  /*!
+   * \brief Return incremented enum value
+   */
+  template < typename ENUM >
+  ENUM Add( ENUM v, int delta )
+  {
+    return ENUM( int(v)+delta );
+  }
 }
 
 //=======================================================================
@@ -213,7 +236,7 @@ typedef struct uvPtStruct
   double x, y; // 2d parameter, normalized [0,1]
   const SMDS_MeshNode * node;
 
-  uvPtStruct(): node(NULL) {}
+  uvPtStruct(const SMDS_MeshNode* n = 0): node(n) {}
 
   inline gp_XY UV() const { return gp_XY( u, v ); }
   inline void  SetUV( const gp_XY& uv ) { u = uv.X(); v = uv.Y(); }
index 51c78a1..3bcb224 100644 (file)
@@ -6145,7 +6145,8 @@ CORBA::Boolean SMESH_Gen_i::IsApplicable ( const char*           theAlgoType,
   if (aCreator)
   {
     TopoDS_Shape shape = GeomObjectToShape( theGeomObject );
-    return shape.IsNull() || aCreator->IsApplicable( shape, toCheckAll );
+    const SMESH_Algo::Features& feat = SMESH_Algo::GetFeatures( theAlgoType );
+    return shape.IsNull() || aCreator->IsApplicable( shape, toCheckAll, feat._dim );
   }
   else
   {
index 054778f..c556187 100644 (file)
@@ -34,6 +34,8 @@
 #include <iostream>
 #include <sstream>
 
+#include <TopExp_Explorer.hxx>
+
 using namespace std;
 
 //=============================================================================
@@ -326,3 +328,24 @@ void SMESH_Hypothesis_i::UpdateAsMeshesRestored()
 {
   // for hyps needing full data restored
 }
+
+//================================================================================
+/*!
+ * \brief Check if a shape includes sub-shapes of a given dimension
+ */
+//================================================================================
+
+bool GenericHypothesisCreator_i::IsShapeOfDim( const TopoDS_Shape & S,
+                                               int                  dim )
+{
+  TopAbs_ShapeEnum shapeType;
+  switch ( dim )
+  {
+  case 0: shapeType = TopAbs_VERTEX; break;
+  case 1: shapeType = TopAbs_EDGE; break;
+  case 2: shapeType = TopAbs_FACE; break;
+  case 3: shapeType = TopAbs_SOLID; break;
+  default: return true;
+  }
+  return TopExp_Explorer( S, shapeType ).More();
+}
index 1408ee3..1551d0a 100644 (file)
@@ -148,9 +148,17 @@ public:
                                      ::SMESH_Gen*            theGenImpl) = 0;
   virtual ~GenericHypothesisCreator_i() {}
 
-  // return the name of IDL module
+  // Return the name of IDL module
   virtual std::string GetModuleName() = 0;
-  virtual bool IsApplicable( const TopoDS_Shape &S, bool toCheckAll ) {return true;}
+
+  // Check if an algorithm is applicable to a shape
+  virtual bool IsApplicable( const TopoDS_Shape &S, bool toCheckAll, int algoDim )
+  {
+    return IsShapeOfDim( S, algoDim );
+  }
+
+  // Check if a shape includes sub-shapes of a given dimension
+  static bool IsShapeOfDim( const TopoDS_Shape &S, int dim );
 };
 
 //=============================================================================
index d0e72a0..58ee0c7 100644 (file)
@@ -27,6 +27,7 @@
 #include "SMDS_VolumeTool.hxx"
 #include "SMESHDS_Mesh.hxx"
 #include "SMESH_Block.hxx"
+#include "SMESH_Indexer.hxx"
 #include "SMESH_Mesh.hxx"
 #include "SMESH_MeshAlgos.hxx"
 #include "SMESH_MesherHelper.hxx"
@@ -59,6 +60,10 @@ using namespace std;
 
 namespace
 {
+  // typedefs for struct's moved to SMESHUtils
+  typedef SMESH_Indexer         _Indexer;
+  typedef SMESH_OrientedIndexer _OrientedIndexer;
+
   enum EBoxSides //!< sides of the block
     {
       B_BOTTOM=0, B_RIGHT, B_TOP, B_LEFT, B_FRONT, B_BACK, NB_BLOCK_SIDES
@@ -145,67 +150,6 @@ namespace
 
   //================================================================================
   /*!
-   * \brief Converter of a pair of integers to a sole index
-   */
-  struct _Indexer
-  {
-    int _xSize, _ySize;
-    _Indexer( int xSize=0, int ySize=0 ): _xSize(xSize), _ySize(ySize) {}
-    int size() const { return _xSize * _ySize; }
-    int operator()(int x, int y) const { return y * _xSize + x; }
-  };
-  //================================================================================
-  /*!
-   * \brief Oriented converter of a pair of integers to a sole index 
-   */
-  class _OrientedIndexer : public _Indexer
-  {
-  public:
-    enum OriFlags //!< types of block side orientation
-      {
-        REV_X = 1, REV_Y = 2, SWAP_XY = 4, MAX_ORI = REV_X|REV_Y|SWAP_XY
-      };
-    _OrientedIndexer( const _Indexer& indexer, const int oriFlags ):
-      _Indexer( indexer._xSize, indexer._ySize ),
-      _xSize (indexer._xSize), _ySize(indexer._ySize),
-      _xRevFun((oriFlags & REV_X) ? & reverse : & lazy),
-      _yRevFun((oriFlags & REV_Y) ? & reverse : & lazy),
-      _swapFun((oriFlags & SWAP_XY ) ? & swap : & lazy)
-    {
-      (*_swapFun)( _xSize, _ySize );
-    }
-    //!< Return index by XY
-    int operator()(int x, int y) const
-    {
-      (*_xRevFun)( x, const_cast<int&>( _xSize ));
-      (*_yRevFun)( y, const_cast<int&>( _ySize ));
-      (*_swapFun)( x, y );
-      return _Indexer::operator()(x,y);
-    }
-    //!< Return index for a corner
-    int corner(bool xMax, bool yMax) const
-    {
-      int x = xMax, y = yMax, size = 2;
-      (*_xRevFun)( x, size );
-      (*_yRevFun)( y, size );
-      (*_swapFun)( x, y );
-      return _Indexer::operator()(x ? _Indexer::_xSize-1 : 0 , y ? _Indexer::_ySize-1 : 0);
-    }
-    int xSize() const { return _xSize; }
-    int ySize() const { return _ySize; }
-  private:
-    _Indexer _indexer;
-    int _xSize, _ySize;
-
-    typedef void (*TFun)(int& x, int& y);
-    TFun _xRevFun, _yRevFun, _swapFun;
-    
-    static void lazy   (int&, int&) {}
-    static void reverse(int& x, int& size) { x = size - x - 1; }
-    static void swap   (int& x, int& y) { std::swap(x,y); }
-  };
-  //================================================================================
-  /*!
    * \brief Structure corresponding to the meshed side of block
    */
   struct _BlockSide
@@ -216,7 +160,7 @@ namespace
     int                          _nbBlocksFound;
 
 #ifdef _DEBUG_ // want to get SIGSEGV in case of invalid index
-#define _grid_access_(pobj, i) pobj->_grid[ ((i) < (int)pobj->_grid.size()) ? i : int(1e100)]
+#define _grid_access_(pobj, i) pobj->_grid[ ((i) < pobj->_grid.size()) ? i : int(1e100)]
 #else
 #define _grid_access_(pobj, i) pobj->_grid[ i ]
 #endif
index 9e0e3b2..286641f 100644 (file)
@@ -142,6 +142,10 @@ ostream & StdMeshers_QuadrangleParams::SaveTo(ostream & save)
          << " " << _enforcedPoints[i].Y()
          << " " << _enforcedPoints[i].Z();
 
+  save << " " << _cornerVertices.size();
+  for ( size_t i = 0; i < _cornerVertices.size(); ++i )
+    save << " " << _cornerVertices[i];
+
   return save;
 }
 
@@ -182,6 +186,17 @@ istream & StdMeshers_QuadrangleParams::LoadFrom(istream & load)
       else
         break;
   }
+
+  if ( load >> nbP && nbP > 0 )
+  {
+    int id;
+    _cornerVertices.reserve( nbP );
+    while ( _cornerVertices.size() < _cornerVertices.capacity() )
+      if ( load >> id )
+        _cornerVertices.push_back( id );
+      else
+        break;
+  }
   return load;
 }
 
index b66b9be..80edff8 100644 (file)
@@ -43,7 +43,7 @@ enum StdMeshers_QuadType
 
 class STDMESHERS_EXPORT StdMeshers_QuadrangleParams: public SMESH_Hypothesis
 {
-public:
+ public:
   StdMeshers_QuadrangleParams(int hypId, SMESH_Gen* gen);
   virtual ~StdMeshers_QuadrangleParams();
 
@@ -61,14 +61,17 @@ public:
   void GetEnforcedNodes( std::vector< TopoDS_Shape >& shapes,
                          std::vector< gp_Pnt >&       points ) const;
 
+  void SetCorners( std::vector< int >& vertexIDs ) { _cornerVertices.swap( vertexIDs ); }
+  const std::vector< int >& GetCorners() const     { return _cornerVertices; }
+
   virtual std::ostream & SaveTo(std::ostream & save);
   virtual std::istream & LoadFrom(std::istream & load);
 
   /*!
    * \brief Initialize start and end length by the mesh built on the geometry
-    * \param theMesh - the built mesh
-    * \param theShape - the geometry of interest
-    * \retval bool - true if parameter values have been successfully defined
+   * \param theMesh - the built mesh
+   * \param theShape - the geometry of interest
+   * \retval bool - true if parameter values have been successfully defined
    */
   virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh,
                                    const TopoDS_Shape& theShape);
@@ -86,6 +89,7 @@ protected:
   StdMeshers_QuadType         _quadType;
   std::vector< TopoDS_Shape > _enforcedVertices;
   std::vector< gp_Pnt >       _enforcedPoints;
+  std::vector< int >          _cornerVertices;
 };
 
 #endif
index e416673..6173866 100644 (file)
@@ -1048,6 +1048,74 @@ namespace
     return true;
   }
 
+  //================================================================================
+  /*!
+   * \brief Return angle between mesh segments of given EDGEs meeting at theVertexNode
+   */
+  //================================================================================
+
+  double getAngleByNodes( const int                  theE1Index,
+                          const int                  theE2Index,
+                          const SMDS_MeshNode*       theVertexNode,
+                          const StdMeshers_FaceSide& theFaceSide,
+                          const gp_Vec&              theFaceNormal)
+  {
+    int eID1 = theFaceSide.EdgeID( theE1Index );
+    int eID2 = theFaceSide.EdgeID( theE2Index );
+
+    const SMDS_MeshNode *n1 = 0, *n2 = 0;
+    bool is1st;
+    SMDS_ElemIteratorPtr segIt = theVertexNode->GetInverseElementIterator( SMDSAbs_Edge );
+    while ( segIt->more() )
+    {
+      const SMDS_MeshElement* seg = segIt->next();
+      int shapeID = seg->GetShapeID();
+      if      ( shapeID == eID1 )
+        is1st = true;
+      else if ( shapeID == eID2 )
+        is1st = false;
+      else
+        continue;
+      ( is1st ? n1 : n2 ) = seg->GetNodeWrap( 1 + seg->GetNodeIndex( theVertexNode ));
+    }
+
+    if ( !n1 || !n2 )
+    {
+      std::vector<const SMDS_MeshNode*> nodes;
+      for ( int is2nd = 0; is2nd < 2; ++is2nd )
+      {
+        const SMDS_MeshNode* & n = is2nd ? n2 : n1;
+        if ( n ) continue;
+        nodes.clear();
+        if ( is2nd ) theFaceSide.GetEdgeNodes( theE2Index, nodes );
+        else         theFaceSide.GetEdgeNodes( theE1Index, nodes );
+        if ( nodes.size() >= 2 )
+        {
+          if ( nodes[0] == theVertexNode )
+            n = nodes[1];
+          else
+            n = nodes[ nodes.size() - 2 ];
+        }
+      }
+    }
+    double angle = -2 * M_PI;
+    if ( n1 && n2 )
+    {
+      SMESH_NodeXYZ p1 = n1, p2 = theVertexNode, p3 = n2;
+      gp_Vec v1( p1, p2 ), v2( p2, p3 );
+      try
+      {
+        angle = v1.AngleWithRef( v2, theFaceNormal );
+      }
+      catch(...)
+      {
+      }
+      if ( std::isnan( angle ))
+        angle = -2 * M_PI;
+    }
+    return angle;
+  }
+
   //--------------------------------------------------------------------------------
   /*!
    * \brief EDGE of a FACE
@@ -1057,6 +1125,7 @@ namespace
     TopoDS_Edge   myEdge;
     TopoDS_Vertex my1stVertex;
     int           myIndex;
+    bool          myIsCorner;   // is fixed corner
     double        myAngle;      // angle at my1stVertex
     int           myNbSegments; // discretization
     Edge*         myPrev;       // preceding EDGE
@@ -1085,6 +1154,7 @@ namespace
 
     // quality criteria to minimize
     int    myOppDiff;
+    int    myIsFixedCorner;
     double myQuartDiff;
     double mySumAngle;
 
@@ -1112,6 +1182,11 @@ namespace
       myOppDiff = ( Abs( myNbSeg[0] - myNbSeg[2] ) +
                     Abs( myNbSeg[1] - myNbSeg[3] ));
 
+      myIsFixedCorner = - totNbSeg * ( myCornerE[0]->myIsCorner +
+                                       myCornerE[1]->myIsCorner +
+                                       myCornerE[2]->myIsCorner +
+                                       myCornerE[3]->myIsCorner );
+
       double nbSideIdeal = totNbSeg / 4.;
       myQuartDiff = -( Min( Min( myNbSeg[0], myNbSeg[1] ),
                             Min( myNbSeg[2], myNbSeg[3] )) / nbSideIdeal );
@@ -1125,7 +1200,7 @@ namespace
     };
 
     // first criterion - equality of nbSeg of opposite sides
-    int    crit1() const { return myOppDiff; }
+    int    crit1() const { return myOppDiff + myIsFixedCorner; }
 
     // second criterion - equality of nbSeg of adjacent sides and sharpness of angles
     double crit2() const { return myQuartDiff + mySumAngle; }
@@ -1143,7 +1218,7 @@ namespace
   //================================================================================
   /*!
    * \brief Unite EDGEs to get a required number of sides
-   *  \param [in] theNbCorners - the required number of sides
+   *  \param [in] theNbCorners - the required number of sides, 3 or 4
    *  \param [in] theConsiderMesh - to considered only meshed VERTEXes
    *  \param [in] theFaceSide - the FACE EDGEs
    *  \param [out] theVertices - the found corner vertices
@@ -1153,7 +1228,7 @@ namespace
   void uniteEdges( const int                   theNbCorners,
                    const bool                  theConsiderMesh,
                    const StdMeshers_FaceSide&  theFaceSide,
-                   const TopoDS_Shape&         theBaseVertex,
+                   const TopTools_MapOfShape&  theFixedVertices,
                    std::vector<TopoDS_Vertex>& theVertices,
                    bool&                       theHaveConcaveVertices)
   {
@@ -1183,23 +1258,28 @@ namespace
 
     // sort edges by angle
     std::multimap< double, Edge* > edgeByAngle;
-    int i, iBase = -1, nbConvexAngles = 0, nbSharpAngles = 0;
+    int i, nbConvexAngles = 0, nbSharpAngles = 0;
+    const SMDS_MeshNode* vertNode = 0;
+    gp_Vec faceNormal;
     const double angTol     = 5. / 180 * M_PI;
     const double sharpAngle = 0.5 * M_PI - angTol;
     Edge* e = edge0;
     for ( i = 0; i < nbEdges; ++i, e = e->myNext )
     {
       e->my1stVertex = SMESH_MesherHelper::IthVertex( 0, e->myEdge );
-      if ( e->my1stVertex.IsSame( theBaseVertex ))
-        iBase = e->myIndex;
+      e->myIsCorner = theFixedVertices.Contains( e->my1stVertex );
 
       e->myAngle = -2 * M_PI;
-      if ( !theConsiderMesh || theFaceSide.VertexNode( e->myIndex ))
+      if ( !theConsiderMesh || ( vertNode = theFaceSide.VertexNode( e->myIndex )))
       {
         e->myAngle = SMESH_MesherHelper::GetAngle( e->myPrev->myEdge, e->myEdge,
-                                                   theFaceSide.Face(), e->my1stVertex );
+                                                   theFaceSide.Face(), e->my1stVertex,
+                                                   &faceNormal );
         if ( e->myAngle > 2 * M_PI ) // GetAngle() failed
           e->myAngle *= -1.;
+        else if ( vertNode && ( 0. <= e->myAngle ) && ( e->myAngle <= angTol ))
+          e->myAngle = getAngleByNodes( e->myPrev->myIndex, e->myIndex,
+                                        vertNode, theFaceSide, faceNormal );
       }
       edgeByAngle.insert( std::make_pair( e->myAngle, e ));
       nbConvexAngles += ( e->myAngle > angTol );
@@ -1227,8 +1307,10 @@ namespace
       // return corners with maximal angles
 
       std::set< int > cornerIndices;
-      if ( iBase != -1 )
-        cornerIndices.insert( iBase );
+      if ( !theFixedVertices.IsEmpty() )
+        for ( i = 0, e = edge0; i < nbEdges; ++i, e = e->myNext )
+          if ( e->myIsCorner )
+            cornerIndices.insert( e->myIndex );
 
       std::multimap< double, Edge* >::reverse_iterator a2e = edgeByAngle.rbegin();
       for (; (int) cornerIndices.size() < theNbCorners; ++a2e )
@@ -1444,7 +1526,20 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face&          theFace,
   myCheckOri = false;
   if ( theVertices.size() > 3 )
   {
-    uniteEdges( nbCorners, theConsiderMesh, faceSide, triaVertex, theVertices, myCheckOri );
+    TopTools_MapOfShape fixedVertices;
+    if ( !triaVertex.IsNull() )
+      fixedVertices.Add( triaVertex );
+    if ( myParams )
+    {
+      const std::vector< int >& vIDs = myParams->GetCorners();
+      for ( size_t i = 0; i < vIDs.size(); ++i )
+      {
+        const TopoDS_Shape& vertex = helper.GetMeshDS()->IndexToShape( vIDs[ i ]);
+        if ( !vertex.IsNull() )
+          fixedVertices.Add( vertex );
+      }
+    }
+    uniteEdges( nbCorners, theConsiderMesh, faceSide, fixedVertices, theVertices, myCheckOri );
   }
 
   if ( nbCorners == 3 && !triaVertex.IsSame( theVertices[0] ))
index 7ce8192..b727e02 100644 (file)
@@ -86,8 +86,7 @@ StdMeshers_Hexa_3D_i::~StdMeshers_Hexa_3D_i()
  */
 //=============================================================================
 
-CORBA::Boolean StdMeshers_Hexa_3D_i::IsApplicable( const TopoDS_Shape &S,
-                                                   CORBA::Boolean toCheckAll )
+bool StdMeshers_Hexa_3D_i::IsApplicable( const TopoDS_Shape &S, bool toCheckAll, int algoDim )
 {
   return ::StdMeshers_Hexa_3D::IsApplicable( S, toCheckAll );
 }
index 3c7f0bd..a8f4f59 100644 (file)
@@ -58,7 +58,7 @@ public:
   ::StdMeshers_Hexa_3D* GetImpl();
 
   // Return true if the algorithm is applicable to a shape
-  static CORBA::Boolean IsApplicable(const TopoDS_Shape &S, CORBA::Boolean toCheckAll);
+  static bool IsApplicable(const TopoDS_Shape &S, bool toCheckAll, int dim);
 };
 
 #endif
index 027da2d..c4320a3 100644 (file)
@@ -63,8 +63,7 @@ StdMeshers_Prism_3D_i::~StdMeshers_Prism_3D_i()
 }
 //-----------------------------------------------------------------------------
 
-CORBA::Boolean StdMeshers_Prism_3D_i::IsApplicable( const TopoDS_Shape &S,
-                                                    CORBA::Boolean toCheckAll )
+bool StdMeshers_Prism_3D_i::IsApplicable( const TopoDS_Shape &S, bool toCheckAll, int algoDim )
 {
   return ::StdMeshers_Prism_3D::IsApplicable( S, toCheckAll );
 }
@@ -99,8 +98,7 @@ StdMeshers_RadialPrism_3D_i::~StdMeshers_RadialPrism_3D_i()
 }
 //-----------------------------------------------------------------------------
 
-CORBA::Boolean StdMeshers_RadialPrism_3D_i::IsApplicable( const TopoDS_Shape &S,
-                                                          CORBA::Boolean toCheckAll )
+bool StdMeshers_RadialPrism_3D_i::IsApplicable( const TopoDS_Shape &S, bool toCheckAll, int )
 {
   return ::StdMeshers_RadialPrism_3D::IsApplicable( S, toCheckAll );
 }
index a98cf47..da067ca 100644 (file)
@@ -57,7 +57,7 @@ public:
   ::StdMeshers_Prism_3D* GetImpl();
 
   // Return true if the algorithm is applicable to a shape
-  static CORBA::Boolean IsApplicable(const TopoDS_Shape &S, CORBA::Boolean toCheckAll);
+  static bool IsApplicable(const TopoDS_Shape &S, bool toCheckAll, int dim);
 };
 
 // ======================================================
@@ -79,7 +79,7 @@ public:
   ::StdMeshers_RadialPrism_3D* GetImpl();
 
   // Return true if the algorithm is applicable to a shape
-  static CORBA::Boolean IsApplicable(const TopoDS_Shape &S, CORBA::Boolean toCheckAll);
+  static bool IsApplicable(const TopoDS_Shape &S, bool toCheckAll, int dim);
 };
 
 
index 366fdd7..217f84b 100644 (file)
@@ -67,8 +67,7 @@ StdMeshers_Projection_3D_i::~StdMeshers_Projection_3D_i()
  */
 //================================================================================
 
-CORBA::Boolean StdMeshers_Projection_3D_i::IsApplicable(const TopoDS_Shape &S,
-                                                        CORBA::Boolean toCheckAll)
+bool StdMeshers_Projection_3D_i::IsApplicable( const TopoDS_Shape &S, bool toCheckAll, int algoDim )
 {
   return ::StdMeshers_Projection_3D::IsApplicable( S, toCheckAll );
 }
index a014111..cfb12ca 100644 (file)
@@ -59,7 +59,7 @@ public:
   ::StdMeshers_Projection_3D* GetImpl();
 
   // Return true if the algorithm is applicable to a shape
-  static CORBA::Boolean IsApplicable(const TopoDS_Shape &S, CORBA::Boolean toCheckAll);
+  static bool IsApplicable(const TopoDS_Shape &S, bool toCheckAll, int dim);
 };
 
 // ======================================================
index dff2f21..45e88d4 100644 (file)
@@ -295,6 +295,43 @@ SMESH::string_array* StdMeshers_QuadrangleParams_i::GetEnfVertices()
 
 //=============================================================================
 /*!
+ * Set corner vertices
+ */
+//=============================================================================
+
+void StdMeshers_QuadrangleParams_i::SetCorners(const SMESH::long_array& theVertexIDs )
+{
+  std::vector< int > ids;
+  for ( CORBA::ULong i = 0; i < theVertexIDs.length(); ++i )
+    ids.push_back( theVertexIDs[i] );
+
+  if ( ids != GetImpl()->GetCorners() )
+  {
+    GetImpl()->SetCorners( ids );
+    SMESH::TPythonDump() << _this() << ".SetCorners( " << theVertexIDs << " )";
+  }
+}
+
+//=============================================================================
+/*!
+ * Return IDs of corner vertices
+ */
+//=============================================================================
+
+SMESH::long_array* StdMeshers_QuadrangleParams_i::GetCorners()
+{
+  const std::vector< int >& ids = GetImpl()->GetCorners();
+
+  SMESH::long_array_var  result = new SMESH::long_array;
+  result->length( ids.size() );
+  for ( size_t i = 0; i < ids.size(); ++i )
+    result[ i ] = ids[ i ];
+
+  return result._retn();
+}
+
+//=============================================================================
+/*!
  *  StdMeshers_QuadrangleParams_i::GetImpl
  *
  *  Get implementation
index 7ef974d..1e14a0b 100644 (file)
@@ -73,6 +73,11 @@ public:
   // Returns entries of shapes defining enforced nodes
   SMESH::string_array* GetEnfVertices();
 
+  // Set corner vertices
+  void SetCorners( const SMESH::long_array& vertexIDs );
+
+  // Return IDs of corner vertices
+  SMESH::long_array* GetCorners();
 
   // Get implementation
   ::StdMeshers_QuadrangleParams* GetImpl();
index 583bf1f..6cc45e1 100644 (file)
@@ -89,8 +89,7 @@ StdMeshers_Quadrangle_2D_i::~StdMeshers_Quadrangle_2D_i()
  */
 //=============================================================================
 
-CORBA::Boolean StdMeshers_Quadrangle_2D_i::IsApplicable( const TopoDS_Shape &S,
-                                                         CORBA::Boolean toCheckAll )
+bool StdMeshers_Quadrangle_2D_i::IsApplicable( const TopoDS_Shape &S, bool toCheckAll, int algoDim )
 {
   return ::StdMeshers_Quadrangle_2D::IsApplicable( S, toCheckAll );
 }
@@ -134,8 +133,8 @@ StdMeshers_QuadFromMedialAxis_1D2D_i::~StdMeshers_QuadFromMedialAxis_1D2D_i()
  */
 //================================================================================
 
-CORBA::Boolean StdMeshers_QuadFromMedialAxis_1D2D_i::IsApplicable( const TopoDS_Shape &S,
-                                                                   CORBA::Boolean toCheckAll )
+bool StdMeshers_QuadFromMedialAxis_1D2D_i::IsApplicable( const TopoDS_Shape &S,
+                                                         bool toCheckAll, int algoDim )
 {
   return ::StdMeshers_QuadFromMedialAxis_1D2D::IsApplicable( S, toCheckAll );
 }
index 9989d06..b2c6d7e 100644 (file)
@@ -58,7 +58,7 @@ class STDMESHERS_I_EXPORT StdMeshers_Quadrangle_2D_i:
   ::StdMeshers_Quadrangle_2D* GetImpl();
 
   // Return true if the algorithm is applicable to a shape
-  static CORBA::Boolean IsApplicable(const TopoDS_Shape &S, CORBA::Boolean toCheckAll);
+  static bool IsApplicable(const TopoDS_Shape &S, bool toCheckAll, int );
 };
 
 // ======================================================
@@ -77,7 +77,7 @@ class STDMESHERS_I_EXPORT StdMeshers_QuadFromMedialAxis_1D2D_i:
   virtual ~StdMeshers_QuadFromMedialAxis_1D2D_i();
 
   // Return true if the algorithm is applicable to a shape
-  static CORBA::Boolean IsApplicable(const TopoDS_Shape &S, CORBA::Boolean toCheckAll);
+  static bool IsApplicable(const TopoDS_Shape &S, bool toCheckAll, int dim);
 };
 
 #endif
index f92a3a8..0faba8a 100644 (file)
@@ -63,7 +63,7 @@ StdMeshers_RadialQuadrangle_1D2D_i::~StdMeshers_RadialQuadrangle_1D2D_i()
 
 //-----------------------------------------------------------------------------
 
-CORBA::Boolean StdMeshers_RadialQuadrangle_1D2D_i::IsApplicable( const TopoDS_Shape &S, CORBA::Boolean toCheckAll )
+bool StdMeshers_RadialQuadrangle_1D2D_i::IsApplicable( const TopoDS_Shape &S, bool toCheckAll, int algoDim )
 {
   return ::StdMeshers_RadialQuadrangle_1D2D::IsApplicable( S, toCheckAll );
 }
index a8ab282..093411c 100644 (file)
@@ -48,7 +48,7 @@ public:
   ::StdMeshers_RadialQuadrangle_1D2D* GetImpl();
 
   // Return true if the algorithm is applicable to a shape
-  static CORBA::Boolean IsApplicable(const TopoDS_Shape &S, CORBA::Boolean toCheckAll);
+  static bool IsApplicable(const TopoDS_Shape &S, bool toCheckAll, int dim);
 };
 
 
index ae09600..602b00a 100644 (file)
@@ -83,21 +83,22 @@ namespace SMESH {
   class ApplicableToAny
   {
   public:
-    static CORBA::Boolean IsApplicable( const TopoDS_Shape &S, CORBA::Boolean toCheckAll )
+    static bool IsApplicable( const TopoDS_Shape &S, bool toCheckAll, int algoDim )
     {
-      return true;
+      return GenericHypothesisCreator_i::IsShapeOfDim( S, algoDim );
     }
   };
 };
+
 template <class T, class TIsApplicable = SMESH::ApplicableToAny>
 class StdHypothesisCreator_i : public HypothesisCreator_i< T >
 {
 public:
   // as we have 'module StdMeshers' in SMESH_BasicHypothesis.idl
   virtual std::string GetModuleName() { return "StdMeshers"; }
-  virtual CORBA::Boolean IsApplicable( const TopoDS_Shape & S, CORBA::Boolean toCheckAll )
+  virtual bool IsApplicable( const TopoDS_Shape & S, bool toCheckAll, int algoDim )
   {
-    return TIsApplicable::IsApplicable( S, toCheckAll );
+    return TIsApplicable::IsApplicable( S, toCheckAll, algoDim );
   }
 };