Salome HOME
23282: EDF 13035 - Problem with submeshes priority
[modules/smesh.git] / src / SMESH / SMESH_Mesh.cxx
index 7c70d5f719d66fcc4a22f05d9874da18e143b908..13747255c7afff32fca9f70317b74800fa29c528 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016  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
@@ -58,7 +58,7 @@
 #include <GEOMUtils.hxx>
 
 #undef _Precision_HeaderFile
-//#include <BRepBndLib.hxx>
+#include <BRepBndLib.hxx>
 #include <BRepPrimAPI_MakeBox.hxx>
 #include <Bnd_Box.hxx>
 #include <TColStd_MapOfInteger.hxx>
 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
 
 #include "Utils_ExceptHandlers.hxx"
+
 #ifndef WIN32
 #include <boost/thread/thread.hpp>
 #include <boost/bind.hpp>
 #else 
-#include <pthread.h> 
+#include <pthread.h>
 #endif
 
 using namespace std;
@@ -111,7 +112,7 @@ SMESH_Mesh::SMESH_Mesh(int               theLocalId,
                        SMESHDS_Document* theDocument):
   _groupId( 0 ), _nbSubShapes( 0 )
 {
-  MESSAGE("SMESH_Mesh::SMESH_Mesh(int localId)");
+  if(MYDEBUG) MESSAGE("SMESH_Mesh::SMESH_Mesh(int localId)");
   _id            = theLocalId;
   _studyId       = theStudyId;
   _gen           = theGen;
@@ -178,7 +179,12 @@ namespace
 
 SMESH_Mesh::~SMESH_Mesh()
 {
-  MESSAGE("SMESH_Mesh::~SMESH_Mesh");
+  if(MYDEBUG) MESSAGE("SMESH_Mesh::~SMESH_Mesh");
+
+  // avoid usual removal of elements while processing RemoveHypothesis( algo ) event
+  SMESHDS_SubMeshIteratorPtr smIt = _myMeshDS->SubMeshes();
+  while ( smIt->more() )
+    const_cast<SMESHDS_SubMesh*>( smIt->next() )->Clear();
 
   // issue 0020340: EDF 1022 SMESH : Crash with FindNodeClosestTo in a second new study
   //   Notify event listeners at least that something happens
@@ -231,6 +237,26 @@ bool SMESH_Mesh::MeshExists( int meshId ) const
   return _myDocument ? bool( _myDocument->GetMesh( meshId )) : false;
 }
 
+//================================================================================
+/*!
+ * \brief Return a mesh by id
+ */
+//================================================================================
+
+SMESH_Mesh* SMESH_Mesh::FindMesh( int meshId ) const
+{
+  if ( _id == meshId )
+    return (SMESH_Mesh*) this;
+
+  if ( StudyContextStruct *aStudyContext = _gen->GetStudyContext( _studyId ))
+  {
+    std::map < int, SMESH_Mesh * >::iterator i_m = aStudyContext->mapMesh.find( meshId );
+    if ( i_m != aStudyContext->mapMesh.end() )
+      return i_m->second;
+  }
+  return NULL;
+}
+
 //=============================================================================
 /*!
  * \brief Set geometry to be meshed
@@ -329,7 +355,25 @@ double SMESH_Mesh::GetShapeDiagonalSize(const TopoDS_Shape & aShape)
 {
   if ( !aShape.IsNull() ) {
     Bnd_Box Box;
-    GEOMUtils::PreciseBoundingBox(aShape, Box);
+    // avoid too long waiting on large shapes. PreciseBoundingBox() was added
+    // to assure same result which else depends on presence of triangulation (IPAL52557).
+    const int maxNbFaces = 4000;
+    int nbFaces = 0;
+    for ( TopExp_Explorer f( aShape, TopAbs_FACE ); f.More() && nbFaces < maxNbFaces; f.Next() )
+      ++nbFaces;
+    bool isPrecise = false;
+    if ( nbFaces < maxNbFaces )
+      try {
+        GEOMUtils::PreciseBoundingBox( aShape, Box );
+        isPrecise = true;
+      }
+      catch (...) {
+        isPrecise = false;
+      }
+    if ( !isPrecise )
+    {
+      BRepBndLib::Add( aShape, Box );
+    }
     if ( !Box.IsVoid() )
       return sqrt( Box.SquareExtent() );
   }
@@ -430,47 +474,38 @@ void SMESH_Mesh::ClearSubMesh(const int theShapeId)
 
 int SMESH_Mesh::UNVToMesh(const char* theFileName)
 {
-  if(MYDEBUG) MESSAGE("UNVToMesh - theFileName = "<<theFileName);
-  if(_isShapeToMesh)
+  if ( _isShapeToMesh )
     throw SALOME_Exception(LOCALIZED("a shape to mesh has already been defined"));
   _isShapeToMesh = false;
+
   DriverUNV_R_SMDS_Mesh myReader;
   myReader.SetMesh(_myMeshDS);
   myReader.SetFile(theFileName);
   myReader.SetMeshId(-1);
   myReader.Perform();
-  if(MYDEBUG){
-    MESSAGE("UNVToMesh - _myMeshDS->NbNodes() = "<<_myMeshDS->NbNodes());
-    MESSAGE("UNVToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges());
-    MESSAGE("UNVToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces());
-    MESSAGE("UNVToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes());
-  }
-  SMDS_MeshGroup* aGroup = (SMDS_MeshGroup*) myReader.GetGroup();
-  if (aGroup != 0) {
+
+  if ( SMDS_MeshGroup* aGroup = (SMDS_MeshGroup*) myReader.GetGroup() )
+  {
     TGroupNamesMap aGroupNames = myReader.GetGroupNamesMap();
-    //const TGroupIdMap& aGroupId = myReader.GetGroupIdMap();
     aGroup->InitSubGroupsIterator();
-    while (aGroup->MoreSubGroups()) {
+    while (aGroup->MoreSubGroups())
+    {
       SMDS_MeshGroup* aSubGroup = (SMDS_MeshGroup*) aGroup->NextSubGroup();
       string aName = aGroupNames[aSubGroup];
       int aId;
-
-      SMESH_Group* aSMESHGroup = AddGroup( aSubGroup->GetType(), aName.c_str(), aId );
-      if ( aSMESHGroup ) {
-        if(MYDEBUG) MESSAGE("UNVToMesh - group added: "<<aName);      
+      if ( SMESH_Group* aSMESHGroup = AddGroup( aSubGroup->GetType(), aName.c_str(), aId ))
+      {
         SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( aSMESHGroup->GetGroupDS() );
         if ( aGroupDS ) {
           aGroupDS->SetStoreName(aName.c_str());
           aSubGroup->InitIterator();
           const SMDS_MeshElement* aElement = 0;
-          while (aSubGroup->More()) {
-            aElement = aSubGroup->Next();
-            if (aElement) {
-              aGroupDS->SMDSGroup().Add(aElement);
-            }
-          }
+          while ( aSubGroup->More() )
+            if (( aElement = aSubGroup->Next() ))
+              aGroupDS->SMDSGroup().Add( aElement );
+
           if (aElement)
-            aGroupDS->SetType(aElement->GetType());
+            aGroupDS->SetType( aElement->GetType() );
         }
       }
     }
@@ -480,37 +515,34 @@ int SMESH_Mesh::UNVToMesh(const char* theFileName)
 
 //=======================================================================
 //function : MEDToMesh
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 int SMESH_Mesh::MEDToMesh(const char* theFileName, const char* theMeshName)
 {
-  if(MYDEBUG) MESSAGE("MEDToMesh - theFileName = "<<theFileName<<", mesh name = "<<theMeshName);
-  if(_isShapeToMesh)
+  if ( _isShapeToMesh )
     throw SALOME_Exception(LOCALIZED("a shape to mesh has already been defined"));
   _isShapeToMesh = false;
+
   DriverMED_R_SMESHDS_Mesh myReader;
   myReader.SetMesh(_myMeshDS);
   myReader.SetMeshId(-1);
   myReader.SetFile(theFileName);
   myReader.SetMeshName(theMeshName);
   Driver_Mesh::Status status = myReader.Perform();
-  if(MYDEBUG){
-    MESSAGE("MEDToMesh - _myMeshDS->NbNodes() = "<<_myMeshDS->NbNodes());
-    MESSAGE("MEDToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges());
-    MESSAGE("MEDToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces());
-    MESSAGE("MEDToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes());
-  }
+#ifdef _DEBUG_
+  SMESH_ComputeErrorPtr er = myReader.GetError();
+  if ( er && !er->IsOK() ) cout << er->myComment << endl;
+#endif
 
   // Reading groups (sub-meshes are out of scope of MED import functionality)
   list<TNameAndType> aGroupNames = myReader.GetGroupNamesAndTypes();
-  if(MYDEBUG) MESSAGE("MEDToMesh - Nb groups = "<<aGroupNames.size()); 
   int anId;
   list<TNameAndType>::iterator name_type = aGroupNames.begin();
-  for ( ; name_type != aGroupNames.end(); name_type++ ) {
+  for ( ; name_type != aGroupNames.end(); name_type++ )
+  {
     SMESH_Group* aGroup = AddGroup( name_type->second, name_type->first.c_str(), anId );
     if ( aGroup ) {
-      if(MYDEBUG) MESSAGE("MEDToMesh - group added: "<<name_type->first.c_str());      
       SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( aGroup->GetGroupDS() );
       if ( aGroupDS ) {
         aGroupDS->SetStoreName( name_type->first.c_str() );
@@ -528,21 +560,16 @@ int SMESH_Mesh::MEDToMesh(const char* theFileName, const char* theMeshName)
 
 int SMESH_Mesh::STLToMesh(const char* theFileName)
 {
-  if(MYDEBUG) MESSAGE("STLToMesh - theFileName = "<<theFileName);
   if(_isShapeToMesh)
     throw SALOME_Exception(LOCALIZED("a shape to mesh has already been defined"));
   _isShapeToMesh = false;
+
   DriverSTL_R_SMDS_Mesh myReader;
   myReader.SetMesh(_myMeshDS);
   myReader.SetFile(theFileName);
   myReader.SetMeshId(-1);
   myReader.Perform();
-  if(MYDEBUG){
-    MESSAGE("STLToMesh - _myMeshDS->NbNodes() = "<<_myMeshDS->NbNodes());
-    MESSAGE("STLToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges());
-    MESSAGE("STLToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces());
-    MESSAGE("STLToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes());
-  }
+
   return 1;
 }
 
@@ -640,8 +667,8 @@ SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape,
 
   // shape
 
-  bool isAlgo = ( anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO );
-  int   event = isAlgo ? SMESH_subMesh::ADD_ALGO : SMESH_subMesh::ADD_HYP;
+  bool                     isAlgo = ( anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO );
+  SMESH_subMesh::algo_event event = isAlgo ? SMESH_subMesh::ADD_ALGO : SMESH_subMesh::ADD_HYP;
 
   SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
 
@@ -699,25 +726,23 @@ SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape,
 //=============================================================================
 
 SMESH_Hypothesis::Hypothesis_Status
-  SMESH_Mesh::RemoveHypothesis(const TopoDS_Shape & aSubShape,
-                               int anHypId)throw(SALOME_Exception)
+SMESH_Mesh::RemoveHypothesis(const TopoDS_Shape & aSubShape,
+                             int                    anHypId) throw( SALOME_Exception )
 {
   Unexpect aCatch(SalomeException);
   if(MYDEBUG) MESSAGE("SMESH_Mesh::RemoveHypothesis");
-  
+
   StudyContextStruct *sc = _gen->GetStudyContext(_studyId);
   if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end())
     throw SALOME_Exception(LOCALIZED("hypothesis does not exist"));
-  
+
   SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId];
-  if(MYDEBUG) {
-    SCRUTE(anHyp->GetType());
-  }
-  
+  if(MYDEBUG) { SCRUTE(anHyp->GetType()); }
+
   // shape 
-  
-  bool isAlgo = ( !anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO );
-  int event = isAlgo ? SMESH_subMesh::REMOVE_ALGO : SMESH_subMesh::REMOVE_HYP;
+
+  bool                     isAlgo = ( !anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO );
+  SMESH_subMesh::algo_event event = isAlgo ? SMESH_subMesh::REMOVE_ALGO : SMESH_subMesh::REMOVE_HYP;
 
   SMESH_subMesh *subMesh = GetSubMesh(aSubShape);
 
@@ -984,7 +1009,6 @@ SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const int anHypId) const
 const list<SMESHDS_Command*> & SMESH_Mesh::GetLog() throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
-  if(MYDEBUG) MESSAGE("SMESH_Mesh::GetLog");
   return _myMeshDS->GetScript()->GetCommands();
 }
 
@@ -996,7 +1020,6 @@ const list<SMESHDS_Command*> & SMESH_Mesh::GetLog() throw(SALOME_Exception)
 void SMESH_Mesh::ClearLog() throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
-  if(MYDEBUG) MESSAGE("SMESH_Mesh::ClearLog");
   _myMeshDS->GetScript()->Clear();
 }
 
@@ -1006,7 +1029,7 @@ void SMESH_Mesh::ClearLog() throw(SALOME_Exception)
  */
 //=============================================================================
 
-SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape)
+SMESH_subMesh * SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape)
   throw(SALOME_Exception)
 {
   int index = _myMeshDS->ShapeToIndex(aSubShape);
@@ -1014,7 +1037,8 @@ SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape)
     return 0;
 
   // for submeshes on GEOM Group
-  if (( !index || index > _nbSubShapes ) && aSubShape.ShapeType() == TopAbs_COMPOUND ) {
+  if (( !index || index > _nbSubShapes ) && aSubShape.ShapeType() == TopAbs_COMPOUND )
+  {
     TopoDS_Iterator it( aSubShape );
     if ( it.More() )
     {
@@ -1082,7 +1106,7 @@ throw(SALOME_Exception)
 
 //================================================================================
 /*!
- * \brief Return submeshes of groups containing the given sub-shape
+ * \brief Return sub-meshes of groups containing the given sub-shape
  */
 //================================================================================
 
@@ -1096,8 +1120,8 @@ SMESH_Mesh::GetGroupSubMeshesContaining(const TopoDS_Shape & aSubShape) const
   if ( !subMesh )
     return found;
 
-  // submeshes of groups have max IDs, so search from the map end
-SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator( /*reverse=*/true ) );
+  // sub-meshes of groups have max IDs, so search from the map end
+  SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator( /*reverse=*/true ) );
   while ( smIt->more() ) {
     SMESH_subMesh*    sm = smIt->next();
     SMESHDS_SubMesh * ds = sm->GetSubMeshDS();
@@ -1123,6 +1147,12 @@ SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator( /*reverse=*/true ) )
           found.push_back( mainSM );
       }
   }
+  else // issue 0023068
+  {
+    if ( SMESH_subMesh * mainSM = GetSubMeshContaining(1) )
+      if ( mainSM->GetSubShape().ShapeType() == TopAbs_COMPOUND )
+        found.push_back( mainSM );
+  }
   return found;
 }
 //=======================================================================
@@ -1160,27 +1190,6 @@ bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp,
   return false;
 }
 
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-// const list < SMESH_subMesh * >&
-// SMESH_Mesh::GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp)
-//   throw(SALOME_Exception)
-// {
-//   _subMeshesUsingHypothesisList.clear();
-//   SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() );
-//   while ( smIt->more() )
-//   {
-//     SMESH_subMesh* aSubMesh = smIt->next();
-//     if ( IsUsedHypothesis ( anHyp, aSubMesh ))
-//       _subMeshesUsingHypothesisList.push_back( aSubMesh );
-//   }
-//   return _subMeshesUsingHypothesisList;
-// }
-
 //=======================================================================
 //function : NotifySubMeshesHypothesisModification
 //purpose  : Say all submeshes using theChangedHyp that it has been modified
@@ -1210,12 +1219,13 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h
 
     // if aSubMesh meshing depends on hyp,
     // we call aSubMesh->AlgoStateEngine( MODIF_HYP, hyp ) that causes either
-    // 1) clearing of already computed aSubMesh or
+    // 1) clearing already computed aSubMesh or
     // 2) changing algo_state from MISSING_HYP to HYP_OK when parameters of hyp becomes valid,
     // other possible changes are not interesting. (IPAL0052457 - assigning hyp performance pb)
     if ( aSubMesh->GetComputeState() != SMESH_subMesh::COMPUTE_OK &&
          aSubMesh->GetComputeState() != SMESH_subMesh::FAILED_TO_COMPUTE &&
-         aSubMesh->GetAlgoState()    != SMESH_subMesh::MISSING_HYP )
+         aSubMesh->GetAlgoState()    != SMESH_subMesh::MISSING_HYP &&
+         !hyp->DataDependOnParams() )
       continue;
 
     const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape();
@@ -1292,7 +1302,7 @@ bool SMESH_Mesh::HasModificationsToDiscard() const
   // return true if the next Compute() will be partial and
   // existing but changed elements may prevent successful re-compute
   bool hasComputed = false, hasNotComputed = false;
-SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() );
+  SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() );
   while ( smIt->more() )
   {
     const SMESH_subMesh* aSubMesh = smIt->next();
@@ -1307,6 +1317,8 @@ SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() );
         hasNotComputed = true;
       if ( hasComputed && hasNotComputed)
         return true;
+
+    default:;
     }
   }
   if ( NbNodes() < 1 )
@@ -1323,15 +1335,15 @@ SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() );
 
 bool SMESH_Mesh::HasDuplicatedGroupNamesMED()
 {
-  //set<string> aGroupNames; // Corrected for Mantis issue 0020028
+  // Corrected for Mantis issue 0020028
   map< SMDSAbs_ElementType, set<string> > aGroupNames;
   for ( map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ )
   {
-    SMESH_Group* aGroup = it->second;
+    SMESH_Group*       aGroup = it->second;
     SMDSAbs_ElementType aType = aGroup->GetGroupDS()->GetType();
-    string aGroupName = aGroup->GetName();
-    aGroupName.resize(MAX_MED_GROUP_NAME_LENGTH);
-    if (!aGroupNames[aType].insert(aGroupName).second)
+    string         aGroupName = aGroup->GetName();
+    aGroupName.resize( MAX_MED_GROUP_NAME_LENGTH );
+    if ( !aGroupNames[aType].insert(aGroupName).second )
       return true;
   }
 
@@ -1536,7 +1548,8 @@ void SMESH_Mesh::ExportSTL(const char *        file,
 //================================================================================
 
 void SMESH_Mesh::ExportCGNS(const char *        file,
-                            const SMESHDS_Mesh* meshDS)
+                            const SMESHDS_Mesh* meshDS,
+                            const char *        meshName)
 {
   int res = Driver_Mesh::DRS_FAIL;
 #ifdef WITH_CGNS
@@ -1544,6 +1557,8 @@ void SMESH_Mesh::ExportCGNS(const char *        file,
   myWriter.SetFile( file );
   myWriter.SetMesh( const_cast<SMESHDS_Mesh*>( meshDS ));
   myWriter.SetMeshName( SMESH_Comment("Mesh_") << meshDS->GetPersistentId());
+  if ( meshName && meshName[0] )
+    myWriter.SetMeshName( meshName );
   res = myWriter.Perform();
 #endif
   if ( res != Driver_Mesh::DRS_OK )
@@ -1744,10 +1759,10 @@ int SMESH_Mesh::NbBiQuadQuadrangles() const throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbPolygons() const throw(SALOME_Exception)
+int SMESH_Mesh::NbPolygons(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbPolygons();
+  return _myMeshDS->GetMeshInfo().NbPolygons(order);
 }
 
 //================================================================================
@@ -1965,8 +1980,8 @@ SMESH_Group* SMESH_Mesh::AddGroup (SMESHDS_GroupBase* groupDS) throw(SALOME_Exce
 
 bool SMESH_Mesh::SynchronizeGroups()
 {
-  int nbGroups = _mapGroup.size();
-  const set<SMESHDS_GroupBase*>& groups = _myMeshDS->GetGroups();
+  const size_t                       nbGroups = _mapGroup.size();
+  const set<SMESHDS_GroupBase*>&       groups = _myMeshDS->GetGroups();
   set<SMESHDS_GroupBase*>::const_iterator gIt = groups.begin();
   for ( ; gIt != groups.end(); ++gIt )
   {
@@ -2041,7 +2056,7 @@ void SMESH_Mesh::SetCallUp( TCallUp* upCaller )
  */
 //=============================================================================
 
-bool SMESH_Mesh::RemoveGroup (const int theGroupID)
+bool SMESH_Mesh::RemoveGroup( const int theGroupID )
 {
   if (_mapGroup.find(theGroupID) == _mapGroup.end())
     return false;
@@ -2077,11 +2092,11 @@ ostream& SMESH_Mesh::Dump(ostream& save)
 {
   int clause = 0;
   save << "========================== Dump contents of mesh ==========================" << endl << endl;
-  save << ++clause << ") Total number of nodes:   \t"    << NbNodes() << endl;
-  save << ++clause << ") Total number of edges:   \t"    << NbEdges() << endl;
-  save << ++clause << ") Total number of faces:   \t"    << NbFaces() << endl;
-  save << ++clause << ") Total number of polygons:\t"    << NbPolygons() << endl;
-  save << ++clause << ") Total number of volumes:\t"     << NbVolumes() << endl;
+  save << ++clause << ") Total number of nodes:      \t" << NbNodes() << endl;
+  save << ++clause << ") Total number of edges:      \t" << NbEdges() << endl;
+  save << ++clause << ") Total number of faces:      \t" << NbFaces() << endl;
+  save << ++clause << ") Total number of polygons:   \t" << NbPolygons() << endl;
+  save << ++clause << ") Total number of volumes:    \t" << NbVolumes() << endl;
   save << ++clause << ") Total number of polyhedrons:\t" << NbPolyhedrons() << endl << endl;
   for ( int isQuadratic = 0; isQuadratic < 2; ++isQuadratic )
   {
@@ -2116,10 +2131,10 @@ ostream& SMESH_Mesh::Dump(ostream& save)
       int nb4 = NbTetras(order);
       int nb5 = NbPyramids(order);
       int nb6 = NbPrisms(order);
-      save << clause << ".1) Number of " << orderStr << " hexahedrons:\t" << nb8 << endl;
+      save << clause << ".1) Number of " << orderStr << " hexahedrons: \t" << nb8 << endl;
       save << clause << ".2) Number of " << orderStr << " tetrahedrons:\t" << nb4 << endl;
       save << clause << ".3) Number of " << orderStr << " prisms:      \t" << nb6 << endl;
-      save << clause << ".4) Number of " << orderStr << " pyramids:\t" << nb5 << endl;
+      save << clause << ".4) Number of " << orderStr << " pyramids:    \t" << nb5 << endl;
       if ( nb8 + nb4 + nb5 + nb6 != NbVolumes(order) ) {
         map<int,int> myVolumesMap;
         SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
@@ -2165,9 +2180,9 @@ SMESH_Group* SMESH_Mesh::ConvertToStandalone ( int theGroupID )
     return aGroup;
 
   SMESH_Group* anOldGrp = (*itg).second;
-  SMESHDS_GroupBase* anOldGrpDS = anOldGrp->GetGroupDS();
-  if ( !anOldGrp || !anOldGrpDS )
+  if ( !anOldGrp || !anOldGrp->GetGroupDS() )
     return aGroup;
+  SMESHDS_GroupBase* anOldGrpDS = anOldGrp->GetGroupDS();
 
   // create new standalone group
   aGroup = new SMESH_Group (theGroupID, this, anOldGrpDS->GetType(), anOldGrp->GetName() );
@@ -2248,8 +2263,8 @@ void SMESH_Mesh::fillAncestorsMap(const TopoDS_Shape& theShape)
         TopTools_ListIteratorOfListOfShape ancIt (ancList);
         while ( ancIt.More() && ancIt.Value().ShapeType() >= memberType )
           ancIt.Next();
-        if ( ancIt.More() )
-          ancList.InsertBefore( theShape, ancIt );
+        if ( ancIt.More() ) ancList.InsertBefore( theShape, ancIt );
+        else                ancList.Append( theShape );
       }
   }
   else // else added for 52457: Addition of hypotheses is 8 time longer than meshing
@@ -2280,27 +2295,31 @@ void SMESH_Mesh::fillAncestorsMap(const TopoDS_Shape& theShape)
  */
 //=============================================================================
 
- bool SMESH_Mesh::SortByMeshOrder(std::vector<SMESH_subMesh*>& theListToSort) const
+bool SMESH_Mesh::SortByMeshOrder(std::vector<SMESH_subMesh*>& theListToSort) const
 {
   if ( !_mySubMeshOrder.size() || theListToSort.size() < 2)
     return true;
   
   bool res = false;
-  vector<SMESH_subMesh*> onlyOrderedList;
+  vector<SMESH_subMesh*> onlyOrderedList, smVec;
+
   // collect all ordered submeshes in one list as pointers
   // and get their positions within theListToSort
   typedef vector<SMESH_subMesh*>::iterator TPosInList;
   map< int, TPosInList > sortedPos;
   TPosInList smBeg = theListToSort.begin(), smEnd = theListToSort.end();
-  TListOfListOfInt::const_iterator listIdsIt = _mySubMeshOrder.begin();
+  TListOfListOfInt::const_iterator      listIdsIt = _mySubMeshOrder.begin();
   for( ; listIdsIt != _mySubMeshOrder.end(); listIdsIt++)
   {
     const TListOfInt& listOfId = *listIdsIt;
     // convert sm ids to sm's
-    vector<SMESH_subMesh*> smVec;
+    smVec.clear();
     TListOfInt::const_iterator idIt = listOfId.begin();
-    for ( ; idIt != listOfId.end(); idIt++ ) {
-      if ( SMESH_subMesh * sm = GetSubMeshContaining( *idIt )) {
+    for ( ; idIt != listOfId.end(); idIt++ )
+    {
+      if ( SMESH_subMesh * sm = GetSubMeshContaining( *idIt ))
+      {
+        smVec.push_back( sm );
         if ( sm->GetSubMeshDS() && sm->GetSubMeshDS()->IsComplexSubmesh() )
         {
           SMESHDS_SubMeshIteratorPtr smdsIt = sm->GetSubMeshDS()->GetSubMeshIterator();
@@ -2311,10 +2330,6 @@ void SMESH_Mesh::fillAncestorsMap(const TopoDS_Shape& theShape)
               smVec.push_back( sm );
           }
         }
-        else
-        {
-          smVec.push_back( sm );
-        }
       }
     }
     // find smVec items in theListToSort