Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/smesh.git] / src / SMESH / SMESH_Mesh.cxx
index bb88ca0bd9ffee65dcde1fb812833c3f7d068292..0b361a52ba302c4eb2285dee267a39119f3fe326 100644 (file)
@@ -35,7 +35,9 @@
 #include "SMESHDS_Group.hxx"
 #include "SMESHDS_Script.hxx"
 #include "SMESHDS_GroupOnGeom.hxx"
 #include "SMESHDS_Group.hxx"
 #include "SMESHDS_Script.hxx"
 #include "SMESHDS_GroupOnGeom.hxx"
+#include "SMESHDS_Document.hxx"
 #include "SMDS_MeshVolume.hxx"
 #include "SMDS_MeshVolume.hxx"
+#include "SMDS_SetIterator.hxx"
 
 #include "utilities.h"
 
 
 #include "utilities.h"
 
 #include "DriverUNV_R_SMDS_Mesh.h"
 #include "DriverSTL_R_SMDS_Mesh.h"
 
 #include "DriverUNV_R_SMDS_Mesh.h"
 #include "DriverSTL_R_SMDS_Mesh.h"
 
-#include <BRepTools_WireExplorer.hxx>
-#include <BRep_Builder.hxx>
-#include <gp_Pnt.hxx>
-
-#include <TCollection_AsciiString.hxx>
+#include <BRepPrimAPI_MakeBox.hxx>
 #include <TopExp.hxx>
 #include <TopExp.hxx>
-#include <TopTools_ListOfShape.hxx>
-#include <TopTools_Array1OfShape.hxx>
+#include <TopExp_Explorer.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
 #include <TopTools_MapOfShape.hxx>
 #include <TopTools_MapOfShape.hxx>
-
-#include <memory>
+#include <TopoDS_Iterator.hxx>
 
 #include "Utils_ExceptHandlers.hxx"
 
 
 #include "Utils_ExceptHandlers.hxx"
 
@@ -72,6 +69,9 @@ static int MYDEBUG = 0;
 static int MYDEBUG = 0;
 #endif
 
 static int MYDEBUG = 0;
 #endif
 
+#define cSMESH_Hyp(h) static_cast<const SMESH_Hypothesis*>(h)
+
+typedef SMESH_HypoFilter THypType;
 
 //=============================================================================
 /*!
 
 //=============================================================================
 /*!
@@ -79,21 +79,23 @@ static int MYDEBUG = 0;
  */
 //=============================================================================
 
  */
 //=============================================================================
 
-SMESH_Mesh::SMESH_Mesh(int theLocalId, 
-                      int theStudyId, 
-                      SMESH_Gen* theGen,
-                      bool theIsEmbeddedMode,
+SMESH_Mesh::SMESH_Mesh(int               theLocalId, 
+                      int               theStudyId, 
+                      SMESH_Gen*        theGen,
+                      bool              theIsEmbeddedMode,
                       SMESHDS_Document* theDocument):
   _groupId( 0 )
 {
                       SMESHDS_Document* theDocument):
   _groupId( 0 )
 {
-  INFOS("SMESH_Mesh::SMESH_Mesh(int localId)");
-  _id = theLocalId;
-  _studyId = theStudyId;
-  _gen = theGen;
-  _myDocument = theDocument;
-  _idDoc = theDocument->NewMesh(theIsEmbeddedMode);
-  _myMeshDS = theDocument->GetMesh(_idDoc);
+  MESSAGE("SMESH_Mesh::SMESH_Mesh(int localId)");
+  _id            = theLocalId;
+  _studyId       = theStudyId;
+  _gen           = theGen;
+  _myDocument    = theDocument;
+  _idDoc         = theDocument->NewMesh(theIsEmbeddedMode);
+  _myMeshDS      = theDocument->GetMesh(_idDoc);
   _isShapeToMesh = false;
   _isShapeToMesh = false;
+  _isAutoColor   = false;
+  _myMeshDS->ShapeToMesh( PseudoShape() );
 }
 
 //=============================================================================
 }
 
 //=============================================================================
@@ -116,7 +118,7 @@ SMESH_Mesh::~SMESH_Mesh()
 
 //=============================================================================
 /*!
 
 //=============================================================================
 /*!
- * 
+ * \brief Set geometry to be meshed
  */
 //=============================================================================
 
  */
 //=============================================================================
 
@@ -124,7 +126,11 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape)
 {
   if(MYDEBUG) MESSAGE("SMESH_Mesh::ShapeToMesh");
 
 {
   if(MYDEBUG) MESSAGE("SMESH_Mesh::ShapeToMesh");
 
-  if ( !_myMeshDS->ShapeToMesh().IsNull() && aShape.IsNull() )
+  if ( !aShape.IsNull() && _isShapeToMesh )
+    throw SALOME_Exception(LOCALIZED ("a shape to mesh has already been defined"));
+
+  // clear current data
+  if ( !_myMeshDS->ShapeToMesh().IsNull() )
   {
     // removal of a shape to mesh, delete objects referring to sub-shapes:
     // - sub-meshes
   {
     // removal of a shape to mesh, delete objects referring to sub-shapes:
     // - sub-meshes
@@ -143,28 +149,56 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape)
       else
         i_gr++;
     }
       else
         i_gr++;
     }
-    _mapPropagationChains.Clear();
+    _mapAncestors.Clear();
+
+    // clear SMESHDS
+    TopoDS_Shape aNullShape;
+    _myMeshDS->ShapeToMesh( aNullShape );
   }
   }
-  else
+
+  // set a new geometry
+  if ( !aShape.IsNull() )
   {
   {
-    if (_isShapeToMesh)
-      throw SALOME_Exception(LOCALIZED ("a shape to mesh has already been defined"));
+    _myMeshDS->ShapeToMesh(aShape);
+    _isShapeToMesh = true;
+
+    // fill _mapAncestors
+    int desType, ancType;
+    for ( desType = TopAbs_VERTEX; desType > TopAbs_COMPOUND; desType-- )
+      for ( ancType = desType - 1; ancType >= TopAbs_COMPOUND; ancType-- )
+        TopExp::MapShapesAndAncestors ( aShape,
+                                        (TopAbs_ShapeEnum) desType,
+                                        (TopAbs_ShapeEnum) ancType,
+                                        _mapAncestors );
   }
   }
-  _isShapeToMesh = true;
-  _myMeshDS->ShapeToMesh(aShape);
-
-  // fill _mapAncestors
-  _mapAncestors.Clear();
-  int desType, ancType;
-  for ( desType = TopAbs_VERTEX; desType > TopAbs_COMPOUND; desType-- )
-    for ( ancType = desType - 1; ancType >= TopAbs_COMPOUND; ancType-- )
-      TopExp::MapShapesAndAncestors ( aShape,
-                                     (TopAbs_ShapeEnum) desType,
-                                     (TopAbs_ShapeEnum) ancType,
-                                     _mapAncestors );
-
-  // NRI : 24/02/03
-  //EAP: 1/9/04 TopExp::MapShapes(aShape, _subShapes); USE the same map of _myMeshDS
+}
+
+//=======================================================================
+/*!
+ * \brief Return geometry to be meshed. (It may be a PseudoShape()!)
+ */
+//=======================================================================
+
+TopoDS_Shape SMESH_Mesh::GetShapeToMesh() const
+{
+  return _myMeshDS->ShapeToMesh();
+}
+
+//=======================================================================
+/*!
+ * \brief Return a solid which is returned by GetShapeToMesh() if
+ *        a real geometry to be meshed was not set
+ */
+//=======================================================================
+
+const TopoDS_Solid& SMESH_Mesh::PseudoShape()
+{
+  static TopoDS_Solid aSolid;
+  if ( aSolid.IsNull() )
+  {
+    aSolid = BRepPrimAPI_MakeBox(1,1,1);
+  }
+  return aSolid;
 }
 
 //=======================================================================
 }
 
 //=======================================================================
@@ -177,7 +211,7 @@ int SMESH_Mesh::UNVToMesh(const char* theFileName)
   if(MYDEBUG) MESSAGE("UNVToMesh - theFileName = "<<theFileName);
   if(_isShapeToMesh)
     throw SALOME_Exception(LOCALIZED("a shape to mesh has already been defined"));
   if(MYDEBUG) MESSAGE("UNVToMesh - theFileName = "<<theFileName);
   if(_isShapeToMesh)
     throw SALOME_Exception(LOCALIZED("a shape to mesh has already been defined"));
-  _isShapeToMesh = true;
+  _isShapeToMesh = false;
   DriverUNV_R_SMDS_Mesh myReader;
   myReader.SetMesh(_myMeshDS);
   myReader.SetFile(theFileName);
   DriverUNV_R_SMDS_Mesh myReader;
   myReader.SetMesh(_myMeshDS);
   myReader.SetFile(theFileName);
@@ -232,7 +266,7 @@ int SMESH_Mesh::MEDToMesh(const char* theFileName, const char* theMeshName)
   if(MYDEBUG) MESSAGE("MEDToMesh - theFileName = "<<theFileName<<", mesh name = "<<theMeshName);
   if(_isShapeToMesh)
     throw SALOME_Exception(LOCALIZED("a shape to mesh has already been defined"));
   if(MYDEBUG) MESSAGE("MEDToMesh - theFileName = "<<theFileName<<", mesh name = "<<theMeshName);
   if(_isShapeToMesh)
     throw SALOME_Exception(LOCALIZED("a shape to mesh has already been defined"));
-  _isShapeToMesh = true;
+  _isShapeToMesh = false;
   DriverMED_R_SMESHDS_Mesh myReader;
   myReader.SetMesh(_myMeshDS);
   myReader.SetMeshId(-1);
   DriverMED_R_SMESHDS_Mesh myReader;
   myReader.SetMesh(_myMeshDS);
   myReader.SetMeshId(-1);
@@ -275,7 +309,7 @@ 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"));
   if(MYDEBUG) MESSAGE("STLToMesh - theFileName = "<<theFileName);
   if(_isShapeToMesh)
     throw SALOME_Exception(LOCALIZED("a shape to mesh has already been defined"));
-  _isShapeToMesh = true;
+  _isShapeToMesh = false;
   DriverSTL_R_SMDS_Mesh myReader;
   myReader.SetMesh(_myMeshDS);
   myReader.SetFile(theFileName);
   DriverSTL_R_SMDS_Mesh myReader;
   myReader.SetMesh(_myMeshDS);
   myReader.SetFile(theFileName);
@@ -325,6 +359,10 @@ SMESH_Hypothesis::Hypothesis_Status
       if ( ret < aBestRet )
         aBestRet = ret;
     }
       if ( ret < aBestRet )
         aBestRet = ret;
     }
+    // bind hypotheses to a group just to know
+    SMESH_Hypothesis *anHyp = _gen->GetStudyContext(_studyId)->mapHypothesis[anHypId];
+    GetMeshDS()->AddHypothesis( aSubShape, anHyp );
+
     if ( SMESH_Hypothesis::IsStatusFatal( aBestRet ))
       return aBestRet;
     return aWorstNotFatal;
     if ( SMESH_Hypothesis::IsStatusFatal( aBestRet ))
       return aBestRet;
     return aWorstNotFatal;
@@ -359,21 +397,17 @@ SMESH_Hypothesis::Hypothesis_Status
 
   // shape 
 
 
   // shape 
 
-  int event;
-  if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO)
-    event = SMESH_subMesh::ADD_HYP;
-  else
-    event = SMESH_subMesh::ADD_ALGO;
+  bool isAlgo = ( !anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO );
+  int event = isAlgo ? SMESH_subMesh::ADD_ALGO : SMESH_subMesh::ADD_HYP;
+
   SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
 
   // subShapes
   if (!SMESH_Hypothesis::IsStatusFatal(ret) &&
   SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
 
   // subShapes
   if (!SMESH_Hypothesis::IsStatusFatal(ret) &&
-      !subMesh->IsApplicableHypotesis( anHyp )) // is added on father
+      anHyp->GetDim() <= SMESH_Gen::GetShapeDim(aSubShape)) // is added on father
   {
   {
-    if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO)
-      event = SMESH_subMesh::ADD_FATHER_HYP;
-    else
-      event = SMESH_subMesh::ADD_FATHER_ALGO;
+    event = isAlgo ? SMESH_subMesh::ADD_FATHER_ALGO : SMESH_subMesh::ADD_FATHER_HYP;
+
     SMESH_Hypothesis::Hypothesis_Status ret2 =
       subMesh->SubMeshesAlgoStateEngine(event, anHyp);
     if (ret2 > ret)
     SMESH_Hypothesis::Hypothesis_Status ret2 =
       subMesh->SubMeshesAlgoStateEngine(event, anHyp);
     if (ret2 > ret)
@@ -382,11 +416,11 @@ SMESH_Hypothesis::Hypothesis_Status
     // check concurent hypotheses on ansestors
     if (ret < SMESH_Hypothesis::HYP_CONCURENT && !isGlobalHyp )
     {
     // check concurent hypotheses on ansestors
     if (ret < SMESH_Hypothesis::HYP_CONCURENT && !isGlobalHyp )
     {
-      const map < int, SMESH_subMesh * >& smMap = subMesh->DependsOn();
-      map < int, SMESH_subMesh * >::const_iterator smIt = smMap.begin();
-      for ( ; smIt != smMap.end(); smIt++ ) {
-        if ( smIt->second->IsApplicableHypotesis( anHyp )) {
-          ret2 = smIt->second->CheckConcurentHypothesis( anHyp->GetType() );
+      SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
+      while ( smIt->more() ) {
+        SMESH_subMesh* sm = smIt->next();
+        if ( sm->IsApplicableHypotesis( anHyp )) {
+          ret2 = sm->CheckConcurentHypothesis( anHyp->GetType() );
           if (ret2 > ret) {
             ret = ret2;
             break;
           if (ret2 > ret) {
             ret = ret2;
             break;
@@ -432,6 +466,9 @@ SMESH_Hypothesis::Hypothesis_Status
       if ( ret < aBestRet )
         aBestRet = ret;
     }
       if ( ret < aBestRet )
         aBestRet = ret;
     }
+    SMESH_Hypothesis *anHyp = _gen->GetStudyContext(_studyId)->mapHypothesis[anHypId];
+    GetMeshDS()->RemoveHypothesis( aSubShape, anHyp );
+
     if ( SMESH_Hypothesis::IsStatusFatal( aBestRet ))
       return aBestRet;
     return aWorstNotFatal;
     if ( SMESH_Hypothesis::IsStatusFatal( aBestRet ))
       return aBestRet;
     return aWorstNotFatal;
@@ -444,14 +481,12 @@ SMESH_Hypothesis::Hypothesis_Status
   SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId];
   int hypType = anHyp->GetType();
   if(MYDEBUG) SCRUTE(hypType);
   SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId];
   int hypType = anHyp->GetType();
   if(MYDEBUG) SCRUTE(hypType);
-  int event;
   
   // shape 
   
   
   // shape 
   
-  if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO)
-    event = SMESH_subMesh::REMOVE_HYP;
-  else
-    event = SMESH_subMesh::REMOVE_ALGO;
+  bool isAlgo = ( !anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO );
+  int event = isAlgo ? SMESH_subMesh::REMOVE_ALGO : SMESH_subMesh::REMOVE_HYP;
+
   SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
 
   // there may appear concurrent hyps that were covered by the removed hyp
   SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
 
   // there may appear concurrent hyps that were covered by the removed hyp
@@ -462,12 +497,10 @@ SMESH_Hypothesis::Hypothesis_Status
 
   // subShapes
   if (!SMESH_Hypothesis::IsStatusFatal(ret) &&
 
   // subShapes
   if (!SMESH_Hypothesis::IsStatusFatal(ret) &&
-      !subMesh->IsApplicableHypotesis( anHyp )) // is removed from father
+      anHyp->GetDim() <= SMESH_Gen::GetShapeDim(aSubShape)) // is removed from father
   {
   {
-    if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO)
-      event = SMESH_subMesh::REMOVE_FATHER_HYP;
-    else
-      event = SMESH_subMesh::REMOVE_FATHER_ALGO;
+    event = isAlgo ? SMESH_subMesh::REMOVE_FATHER_ALGO : SMESH_subMesh::REMOVE_FATHER_HYP;
+
     SMESH_Hypothesis::Hypothesis_Status ret2 =
       subMesh->SubMeshesAlgoStateEngine(event, anHyp);
     if (ret2 > ret) // more severe
     SMESH_Hypothesis::Hypothesis_Status ret2 =
       subMesh->SubMeshesAlgoStateEngine(event, anHyp);
     if (ret2 > ret) // more severe
@@ -476,11 +509,11 @@ SMESH_Hypothesis::Hypothesis_Status
     // check concurent hypotheses on ansestors
     if (ret < SMESH_Hypothesis::HYP_CONCURENT && !IsMainShape( aSubShape ) )
     {
     // check concurent hypotheses on ansestors
     if (ret < SMESH_Hypothesis::HYP_CONCURENT && !IsMainShape( aSubShape ) )
     {
-      const map < int, SMESH_subMesh * >& smMap = subMesh->DependsOn();
-      map < int, SMESH_subMesh * >::const_iterator smIt = smMap.begin();
-      for ( ; smIt != smMap.end(); smIt++ ) {
-        if ( smIt->second->IsApplicableHypotesis( anHyp )) {
-          ret2 = smIt->second->CheckConcurentHypothesis( anHyp->GetType() );
+      SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
+      while ( smIt->more() ) {
+        SMESH_subMesh* sm = smIt->next();
+        if ( sm->IsApplicableHypotesis( anHyp )) {
+          ret2 = sm->CheckConcurentHypothesis( anHyp->GetType() );
           if (ret2 > ret) {
             ret = ret2;
             break;
           if (ret2 > ret) {
             ret = ret2;
             break;
@@ -501,17 +534,6 @@ SMESH_Hypothesis::Hypothesis_Status
  */
 //=============================================================================
 
  */
 //=============================================================================
 
-SMESHDS_Mesh * SMESH_Mesh::GetMeshDS()
-{
-  return _myMeshDS;
-}
-
-//=============================================================================
-/*!
- * 
- */
-//=============================================================================
-
 const list<const SMESHDS_Hypothesis*>&
 SMESH_Mesh::GetHypothesisList(const TopoDS_Shape & aSubShape) const
   throw(SALOME_Exception)
 const list<const SMESHDS_Hypothesis*>&
 SMESH_Mesh::GetHypothesisList(const TopoDS_Shape & aSubShape) const
   throw(SALOME_Exception)
@@ -521,8 +543,13 @@ SMESH_Mesh::GetHypothesisList(const TopoDS_Shape & aSubShape) const
 }
 
 //=======================================================================
 }
 
 //=======================================================================
-//function : GetHypothesis
-//purpose  : 
+/*!
+ * \brief Return the hypothesis assigned to the shape
+  * \param aSubShape - the shape to check
+  * \param aFilter - the hypothesis filter
+  * \param andAncestors - flag to check hypos assigned to ancestors of the shape
+  * \retval SMESH_Hypothesis* - the first hypo passed through aFilter
+ */
 //=======================================================================
 
 const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const TopoDS_Shape &    aSubShape,
 //=======================================================================
 
 const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const TopoDS_Shape &    aSubShape,
@@ -533,7 +560,7 @@ const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const TopoDS_Shape &    aSubS
     const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(aSubShape);
     list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
     for ( ; hyp != hypList.end(); hyp++ ) {
     const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(aSubShape);
     list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
     for ( ; hyp != hypList.end(); hyp++ ) {
-      const SMESH_Hypothesis * h = static_cast<const SMESH_Hypothesis*>( *hyp );
+      const SMESH_Hypothesis * h = cSMESH_Hyp( *hyp );
       if ( aFilter.IsOk( h, aSubShape))
         return h;
     }
       if ( aFilter.IsOk( h, aSubShape))
         return h;
     }
@@ -546,7 +573,7 @@ const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const TopoDS_Shape &    aSubS
       const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(it.Value());
       list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
       for ( ; hyp != hypList.end(); hyp++ ) {
       const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(it.Value());
       list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
       for ( ; hyp != hypList.end(); hyp++ ) {
-        const SMESH_Hypothesis * h = static_cast<const SMESH_Hypothesis*>( *hyp );
+        const SMESH_Hypothesis * h = cSMESH_Hyp( *hyp );
         if (aFilter.IsOk( h, it.Value() ))
           return h;
       }
         if (aFilter.IsOk( h, it.Value() ))
           return h;
       }
@@ -555,11 +582,6 @@ const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const TopoDS_Shape &    aSubS
   return 0;
 }
 
   return 0;
 }
 
-//=======================================================================
-//function : GetHypotheses
-//purpose  : 
-//=======================================================================
-
 //================================================================================
 /*!
  * \brief Return hypothesis assigned to the shape
 //================================================================================
 /*!
  * \brief Return hypothesis assigned to the shape
@@ -579,21 +601,30 @@ int SMESH_Mesh::GetHypotheses(const TopoDS_Shape &                aSubShape,
   set<string> hypTypes; // to exclude same type hypos from the result list
   int nbHyps = 0;
 
   set<string> hypTypes; // to exclude same type hypos from the result list
   int nbHyps = 0;
 
+  // only one main hypothesis is allowed
+  bool mainHypFound = false;
+
   // fill in hypTypes
   list<const SMESHDS_Hypothesis*>::const_iterator hyp;
   // fill in hypTypes
   list<const SMESHDS_Hypothesis*>::const_iterator hyp;
-  for ( hyp = aHypList.begin(); hyp != aHypList.end(); hyp++ )
+  for ( hyp = aHypList.begin(); hyp != aHypList.end(); hyp++ ) {
     if ( hypTypes.insert( (*hyp)->GetName() ).second )
       nbHyps++;
     if ( hypTypes.insert( (*hyp)->GetName() ).second )
       nbHyps++;
+    if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() )
+      mainHypFound = true;
+  }
 
   // get hypos from aSubShape
   {
     const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(aSubShape);
     for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ )
 
   // get hypos from aSubShape
   {
     const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(aSubShape);
     for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ )
-      if ( aFilter.IsOk (static_cast<const SMESH_Hypothesis*>( *hyp ), aSubShape) &&
+      if ( aFilter.IsOk (cSMESH_Hyp( *hyp ), aSubShape) &&
+           ( cSMESH_Hyp(*hyp)->IsAuxiliary() || !mainHypFound ) &&
            hypTypes.insert( (*hyp)->GetName() ).second )
       {
         aHypList.push_back( *hyp );
         nbHyps++;
            hypTypes.insert( (*hyp)->GetName() ).second )
       {
         aHypList.push_back( *hyp );
         nbHyps++;
+        if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() )
+          mainHypFound = true;
       }
   }
 
       }
   }
 
@@ -608,10 +639,14 @@ int SMESH_Mesh::GetHypotheses(const TopoDS_Shape &                aSubShape,
         continue;
       const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(it.Value());
       for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ )
         continue;
       const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(it.Value());
       for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ )
-        if (aFilter.IsOk( static_cast<const SMESH_Hypothesis*>( *hyp ), it.Value() ) &&
-            hypTypes.insert( (*hyp)->GetName() ).second ) {
+        if (aFilter.IsOk( cSMESH_Hyp( *hyp ), it.Value() ) &&
+            ( cSMESH_Hyp(*hyp)->IsAuxiliary() || !mainHypFound ) &&
+            hypTypes.insert( (*hyp)->GetName() ).second )
+        {
           aHypList.push_back( *hyp );
           nbHyps++;
           aHypList.push_back( *hyp );
           nbHyps++;
+          if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() )
+            mainHypFound = true;
         }
     }
   }
         }
     }
   }
@@ -643,29 +678,6 @@ void SMESH_Mesh::ClearLog() throw(SALOME_Exception)
   _myMeshDS->GetScript()->Clear();
 }
 
   _myMeshDS->GetScript()->Clear();
 }
 
-//=============================================================================
-/*!
- * 
- */
-//=============================================================================
-
-int SMESH_Mesh::GetId()
-{
-  if(MYDEBUG) MESSAGE("SMESH_Mesh::GetId");
-  return _id;
-}
-
-//=============================================================================
-/*!
- * 
- */
-//=============================================================================
-
-SMESH_Gen *SMESH_Mesh::GetGen()
-{
-  return _gen;
-}
-
 //=============================================================================
 /*!
  * Get or Create the SMESH_subMesh object implementation
 //=============================================================================
 /*!
  * Get or Create the SMESH_subMesh object implementation
@@ -708,7 +720,7 @@ SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape)
  */
 //=============================================================================
 
  */
 //=============================================================================
 
-SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const TopoDS_Shape & aSubShape)
+SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const TopoDS_Shape & aSubShape) const
   throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
   throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
@@ -716,13 +728,12 @@ SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const TopoDS_Shape & aSubShape)
   
   int index = _myMeshDS->ShapeToIndex(aSubShape);
 
   
   int index = _myMeshDS->ShapeToIndex(aSubShape);
 
-  map <int, SMESH_subMesh *>::iterator i_sm = _mapSubMesh.find(index);
+  map <int, SMESH_subMesh *>::const_iterator i_sm = _mapSubMesh.find(index);
   if ( i_sm != _mapSubMesh.end())
     aSubMesh = i_sm->second;
 
   return aSubMesh;
 }
   if ( i_sm != _mapSubMesh.end())
     aSubMesh = i_sm->second;
 
   return aSubMesh;
 }
-
 //=============================================================================
 /*!
  * Get the SMESH_subMesh object implementation. Dont create it, return null
 //=============================================================================
 /*!
  * Get the SMESH_subMesh object implementation. Dont create it, return null
@@ -730,17 +741,51 @@ SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const TopoDS_Shape & aSubShape)
  */
 //=============================================================================
 
  */
 //=============================================================================
 
-SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const int aShapeID)
+SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const int aShapeID) const
 throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
   
 throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
   
-  map <int, SMESH_subMesh *>::iterator i_sm = _mapSubMesh.find(aShapeID);
+  map <int, SMESH_subMesh *>::const_iterator i_sm = _mapSubMesh.find(aShapeID);
   if (i_sm == _mapSubMesh.end())
     return NULL;
   return i_sm->second;
 }
   if (i_sm == _mapSubMesh.end())
     return NULL;
   return i_sm->second;
 }
+//================================================================================
+/*!
+ * \brief Return submeshes of groups containing the given subshape
+ */
+//================================================================================
 
 
+list<SMESH_subMesh*>
+SMESH_Mesh::GetGroupSubMeshesContaining(const TopoDS_Shape & aSubShape) const
+  throw(SALOME_Exception)
+{
+  Unexpect aCatch(SalomeException);
+  list<SMESH_subMesh*> found;
+
+  SMESH_subMesh * subMesh = GetSubMeshContaining(aSubShape);
+  if ( !subMesh )
+    return found;
+
+  // submeshes of groups have max IDs, so search from the map end
+  map<int, SMESH_subMesh *>::const_reverse_iterator i_sm;
+  for ( i_sm = _mapSubMesh.rbegin(); i_sm != _mapSubMesh.rend(); ++i_sm) {
+    SMESHDS_SubMesh * ds = i_sm->second->GetSubMeshDS();
+    if ( ds && ds->IsComplexSubmesh() ) {
+      TopExp_Explorer exp( i_sm->second->GetSubShape(), aSubShape.ShapeType() );
+      for ( ; exp.More(); exp.Next() ) {
+        if ( aSubShape.IsSame( exp.Current() )) {
+          found.push_back( i_sm->second );
+          break;
+        }
+      }
+    } else {
+      break;
+    }
+  }
+  return found;
+}
 //=======================================================================
 //function : IsUsedHypothesis
 //purpose  : Return True if anHyp is used to mesh aSubShape
 //=======================================================================
 //function : IsUsedHypothesis
 //purpose  : Return True if anHyp is used to mesh aSubShape
@@ -808,15 +853,12 @@ SMESH_Mesh::GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp)
 //purpose  : Say all submeshes using theChangedHyp that it has been modified
 //=======================================================================
 
 //purpose  : Say all submeshes using theChangedHyp that it has been modified
 //=======================================================================
 
-void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* theChangedHyp)
+void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* hyp)
 {
   Unexpect aCatch(SalomeException);
 
 {
   Unexpect aCatch(SalomeException);
 
-  const SMESH_Hypothesis* hyp = static_cast<const SMESH_Hypothesis*>(theChangedHyp);
-
   const SMESH_Algo *foundAlgo = 0;
   const SMESH_Algo *foundAlgo = 0;
-  SMESH_HypoFilter algoKind( SMESH_HypoFilter::IsAlgo() );
-  SMESH_HypoFilter compatibleHypoKind;
+  SMESH_HypoFilter algoKind, compatibleHypoKind;
   list <const SMESHDS_Hypothesis * > usedHyps;
 
 
   list <const SMESHDS_Hypothesis * > usedHyps;
 
 
@@ -829,7 +871,7 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* t
       const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape();
 
       if ( !foundAlgo ) // init filter for algo search
       const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape();
 
       if ( !foundAlgo ) // init filter for algo search
-        algoKind.And( algoKind.IsApplicableTo( aSubShape ));
+        algoKind.Init( THypType::IsAlgo() ).And( THypType::IsApplicableTo( aSubShape ));
       
       const SMESH_Algo *algo = static_cast<const SMESH_Algo*>
         ( GetHypothesis( aSubShape, algoKind, true ));
       
       const SMESH_Algo *algo = static_cast<const SMESH_Algo*>
         ( GetHypothesis( aSubShape, algoKind, true ));
@@ -851,16 +893,31 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* t
         if ( GetHypotheses( aSubShape, compatibleHypoKind, usedHyps, true ) &&
              find( usedHyps.begin(), usedHyps.end(), hyp ) != usedHyps.end() )
         {
         if ( GetHypotheses( aSubShape, compatibleHypoKind, usedHyps, true ) &&
              find( usedHyps.begin(), usedHyps.end(), hyp ) != usedHyps.end() )
         {
-          aSubMesh->ComputeStateEngine(SMESH_subMesh::MODIF_HYP);
-
-          if ( algo->GetDim() == 1 && IsPropagationHypothesis( aSubShape ))
-            CleanMeshOnPropagationChain( aSubShape );
+          aSubMesh->AlgoStateEngine(SMESH_subMesh::MODIF_HYP,
+                                    const_cast< SMESH_Hypothesis*>( hyp ));
         }
       }
     }
   }
 }
 
         }
       }
     }
   }
 }
 
+//=============================================================================
+/*!
+ *  Auto color functionality
+ */
+//=============================================================================
+void SMESH_Mesh::SetAutoColor(bool theAutoColor) throw(SALOME_Exception)
+{
+  Unexpect aCatch(SalomeException);
+  _isAutoColor = theAutoColor;
+}
+
+bool SMESH_Mesh::GetAutoColor() throw(SALOME_Exception)
+{
+  Unexpect aCatch(SalomeException);
+  return _isAutoColor;
+}
+
 //=============================================================================
 /*! Export* methods.
  *  To store mesh contents on disk in different formats.
 //=============================================================================
 /*! Export* methods.
  *  To store mesh contents on disk in different formats.
@@ -973,221 +1030,156 @@ void SMESH_Mesh::ExportSTL(const char *file, const bool isascii) throw(SALOME_Ex
   myWriter.Perform();
 }
 
   myWriter.Perform();
 }
 
-//=============================================================================
+//================================================================================
 /*!
 /*!
- *  
+ * \brief Return number of nodes in the mesh
  */
  */
-//=============================================================================
+//================================================================================
+
 int SMESH_Mesh::NbNodes() throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
   return _myMeshDS->NbNodes();
 }
 
 int SMESH_Mesh::NbNodes() throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
   return _myMeshDS->NbNodes();
 }
 
-//=============================================================================
+//================================================================================
 /*!
 /*!
- *  
+ * \brief  Return number of edges of given order in the mesh
  */
  */
-//=============================================================================
-int SMESH_Mesh::NbEdges(ElementOrder order) throw(SALOME_Exception)
+//================================================================================
+
+int SMESH_Mesh::NbEdges(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
 {
   Unexpect aCatch(SalomeException);
-  if (order == ORDER_ANY)
-    return _myMeshDS->NbEdges();
-
-  int Nb = 0;
-  SMDS_EdgeIteratorPtr it = _myMeshDS->edgesIterator();
-  while (it->more()) {
-    const SMDS_MeshEdge* cur = it->next();
-    if ( order == ORDER_LINEAR && !cur->IsQuadratic() ||
-         order == ORDER_QUADRATIC && cur->IsQuadratic() )
-      Nb++;
-  }
-  return Nb;
+  return _myMeshDS->GetMeshInfo().NbEdges(order);
 }
 
 }
 
-//=============================================================================
+//================================================================================
 /*!
 /*!
- *  
+ * \brief Return number of faces of given order in the mesh
  */
  */
-//=============================================================================
-int SMESH_Mesh::NbFaces(ElementOrder order) throw(SALOME_Exception)
+//================================================================================
+
+int SMESH_Mesh::NbFaces(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
 {
   Unexpect aCatch(SalomeException);
-  if (order == ORDER_ANY)
-    return _myMeshDS->NbFaces();
-
-  int Nb = 0;
-  SMDS_FaceIteratorPtr it = _myMeshDS->facesIterator();
-  while (it->more()) {
-    const SMDS_MeshFace* cur = it->next();
-    if ( order == ORDER_LINEAR && !cur->IsQuadratic() ||
-         order == ORDER_QUADRATIC && cur->IsQuadratic() )
-      Nb++;
-  }
-  return Nb;
+  return _myMeshDS->GetMeshInfo().NbFaces(order);
 }
 
 }
 
-///////////////////////////////////////////////////////////////////////////////
-/// Return the number of 3 nodes faces in the mesh. This method run in O(n)
-///////////////////////////////////////////////////////////////////////////////
-int SMESH_Mesh::NbTriangles(ElementOrder order) throw(SALOME_Exception)
+//================================================================================
+/*!
+ * \brief Return the number of faces in the mesh
+ */
+//================================================================================
+
+int SMESH_Mesh::NbTriangles(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
 {
   Unexpect aCatch(SalomeException);
-  int Nb = 0;
-  
-  SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator();
-  while (itFaces->more()) {
-    const SMDS_MeshFace* curFace = itFaces->next();
-    int nbnod = curFace->NbNodes();
-    if ( !curFace->IsPoly() && 
-        ( order == ORDER_ANY && (nbnod==3 || nbnod==6) ||
-           order == ORDER_LINEAR && nbnod==3 ||
-           order == ORDER_QUADRATIC && nbnod==6 ) )
-      Nb++;
-  }
-  return Nb;
+  return _myMeshDS->GetMeshInfo().NbTriangles(order);
 }
 
 }
 
-///////////////////////////////////////////////////////////////////////////////
-/// Return the number of 4 nodes faces in the mesh. This method run in O(n)
-///////////////////////////////////////////////////////////////////////////////
-int SMESH_Mesh::NbQuadrangles(ElementOrder order) throw(SALOME_Exception)
+//================================================================================
+/*!
+ * \brief Return the number nodes faces in the mesh
+ */
+//================================================================================
+
+int SMESH_Mesh::NbQuadrangles(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
 {
   Unexpect aCatch(SalomeException);
-  int Nb = 0;
-  
-  SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator();
-  while (itFaces->more()) {
-    const SMDS_MeshFace* curFace = itFaces->next();
-    int nbnod = curFace->NbNodes();
-    if ( !curFace->IsPoly() && 
-        ( order == ORDER_ANY && (nbnod==4 || nbnod==8) ||
-           order == ORDER_LINEAR && nbnod==4 ||
-           order == ORDER_QUADRATIC && nbnod==8 ) )
-      Nb++;
-  }
-  return Nb;
+  return _myMeshDS->GetMeshInfo().NbQuadrangles(order);
 }
 
 }
 
-///////////////////////////////////////////////////////////////////////////////
-/// Return the number of polygonal faces in the mesh. This method run in O(n)
-///////////////////////////////////////////////////////////////////////////////
+//================================================================================
+/*!
+ * \brief Return the number of polygonal faces in the mesh
+ */
+//================================================================================
+
 int SMESH_Mesh::NbPolygons() throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
 int SMESH_Mesh::NbPolygons() throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
-  int Nb = 0;
-  SMDS_FaceIteratorPtr itFaces = _myMeshDS->facesIterator();
-  while (itFaces->more())
-    if (itFaces->next()->IsPoly()) Nb++;
-  return Nb;
+  return _myMeshDS->GetMeshInfo().NbPolygons();
 }
 
 }
 
-//=============================================================================
+//================================================================================
 /*!
 /*!
- *  
+ * \brief Return number of volumes of given order in the mesh
  */
  */
-//=============================================================================
-int SMESH_Mesh::NbVolumes(ElementOrder order) throw(SALOME_Exception)
+//================================================================================
+
+int SMESH_Mesh::NbVolumes(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
 {
   Unexpect aCatch(SalomeException);
-  if (order == ORDER_ANY)
-    return _myMeshDS->NbVolumes();
-
-  int Nb = 0;
-  SMDS_VolumeIteratorPtr it = _myMeshDS->volumesIterator();
-  while (it->more()) {
-    const SMDS_MeshVolume* cur = it->next();
-    if ( order == ORDER_LINEAR && !cur->IsQuadratic() ||
-         order == ORDER_QUADRATIC && cur->IsQuadratic() )
-      Nb++;
-  }
-  return Nb;
+  return _myMeshDS->GetMeshInfo().NbVolumes(order);
 }
 
 }
 
-int SMESH_Mesh::NbTetras(ElementOrder order) throw(SALOME_Exception)
+//================================================================================
+/*!
+ * \brief  Return number of tetrahedrons of given order in the mesh
+ */
+//================================================================================
+
+int SMESH_Mesh::NbTetras(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
 {
   Unexpect aCatch(SalomeException);
-  int Nb = 0;
-  SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
-  while (itVolumes->more()) {
-    const SMDS_MeshVolume* curVolume = itVolumes->next();
-    int nbnod = curVolume->NbNodes();
-    if ( !curVolume->IsPoly() && 
-        ( order == ORDER_ANY && (nbnod==4 || nbnod==10) ||
-           order == ORDER_LINEAR && nbnod==4 ||
-           order == ORDER_QUADRATIC && nbnod==10 ) )
-      Nb++;
-  }
-  return Nb;
+  return _myMeshDS->GetMeshInfo().NbTetras(order);
 }
 
 }
 
-int SMESH_Mesh::NbHexas(ElementOrder order) throw(SALOME_Exception)
+//================================================================================
+/*!
+ * \brief  Return number of hexahedrons of given order in the mesh
+ */
+//================================================================================
+
+int SMESH_Mesh::NbHexas(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
 {
   Unexpect aCatch(SalomeException);
-  int Nb = 0;
-  SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
-  while (itVolumes->more()) {
-    const SMDS_MeshVolume* curVolume = itVolumes->next();
-    int nbnod = curVolume->NbNodes();
-    if ( !curVolume->IsPoly() && 
-        ( order == ORDER_ANY && (nbnod==8 || nbnod==20) ||
-           order == ORDER_LINEAR && nbnod==8 ||
-           order == ORDER_QUADRATIC && nbnod==20 ) )
-      Nb++;
-  }
-  return Nb;
+  return _myMeshDS->GetMeshInfo().NbHexas(order);
 }
 
 }
 
-int SMESH_Mesh::NbPyramids(ElementOrder order) throw(SALOME_Exception)
+//================================================================================
+/*!
+ * \brief  Return number of pyramids of given order in the mesh
+ */
+//================================================================================
+
+int SMESH_Mesh::NbPyramids(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
 {
   Unexpect aCatch(SalomeException);
-  int Nb = 0;
-  SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
-  while (itVolumes->more()) {
-    const SMDS_MeshVolume* curVolume = itVolumes->next();
-    int nbnod = curVolume->NbNodes();
-    if ( !curVolume->IsPoly() && 
-        ( order == ORDER_ANY && (nbnod==5 || nbnod==13) ||
-           order == ORDER_LINEAR && nbnod==5 ||
-           order == ORDER_QUADRATIC && nbnod==13 ) )
-      Nb++;
-  }
-  return Nb;
+  return _myMeshDS->GetMeshInfo().NbPyramids(order);
 }
 
 }
 
-int SMESH_Mesh::NbPrisms(ElementOrder order) throw(SALOME_Exception)
+//================================================================================
+/*!
+ * \brief  Return number of prisms (penthahedrons) of given order in the mesh
+ */
+//================================================================================
+
+int SMESH_Mesh::NbPrisms(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
 {
   Unexpect aCatch(SalomeException);
-  int Nb = 0;
-  SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
-  while (itVolumes->more()) {
-    const SMDS_MeshVolume* curVolume = itVolumes->next();
-    int nbnod = curVolume->NbNodes();
-    if ( !curVolume->IsPoly() && 
-        ( order == ORDER_ANY && (nbnod==6 || nbnod==15) ||
-           order == ORDER_LINEAR && nbnod==6 ||
-           order == ORDER_QUADRATIC && nbnod==15 ) )
-      Nb++;
-  }
-  return Nb;
+  return _myMeshDS->GetMeshInfo().NbPrisms(order);
 }
 
 }
 
+//================================================================================
+/*!
+ * \brief  Return number of polyhedrons in the mesh
+ */
+//================================================================================
+
 int SMESH_Mesh::NbPolyhedrons() throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
 int SMESH_Mesh::NbPolyhedrons() throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
-  int Nb = 0;
-  SMDS_VolumeIteratorPtr itVolumes = _myMeshDS->volumesIterator();
-  while (itVolumes->more())
-    if (itVolumes->next()->IsPoly()) Nb++;
-  return Nb;
+  return _myMeshDS->GetMeshInfo().NbPolyhedrons();
 }
 
 }
 
-//=============================================================================
+//================================================================================
 /*!
 /*!
- *  
+ * \brief  Return number of submeshes in the mesh
  */
  */
-//=============================================================================
+//================================================================================
+
 int SMESH_Mesh::NbSubMesh() throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
 int SMESH_Mesh::NbSubMesh() throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
@@ -1203,7 +1195,7 @@ bool SMESH_Mesh::IsNotConformAllowed() const
 {
   if(MYDEBUG) MESSAGE("SMESH_Mesh::IsNotConformAllowed");
 
 {
   if(MYDEBUG) MESSAGE("SMESH_Mesh::IsNotConformAllowed");
 
-  SMESH_HypoFilter filter( SMESH_HypoFilter::HasName( "NotConformAllowed" ));
+  static SMESH_HypoFilter filter( SMESH_HypoFilter::HasName( "NotConformAllowed" ));
   return GetHypothesis( _myMeshDS->ShapeToMesh(), filter, false );
 }
 
   return GetHypothesis( _myMeshDS->ShapeToMesh(), filter, false );
 }
 
@@ -1237,9 +1229,21 @@ SMESH_Group* SMESH_Mesh::AddGroup (const SMDSAbs_ElementType theType,
   return aGroup;
 }
 
   return aGroup;
 }
 
+//================================================================================
+/*!
+ * \brief Return iterator on all existing groups
+ */
+//================================================================================
+
+SMESH_Mesh::GroupIteratorPtr SMESH_Mesh::GetGroups() const
+{
+  typedef map <int, SMESH_Group *> TMap;
+  return GroupIteratorPtr( new SMDS_mapIterator<TMap>( _mapGroup ));
+}
+
 //=============================================================================
 /*!
 //=============================================================================
 /*!
- *  
+ * \brief Return a group by ID
  */
 //=============================================================================
 
  */
 //=============================================================================
 
@@ -1253,11 +1257,11 @@ SMESH_Group* SMESH_Mesh::GetGroup (const int theGroupID)
 
 //=============================================================================
 /*!
 
 //=============================================================================
 /*!
- *  
+ * \brief Return IDs of all groups
  */
 //=============================================================================
 
  */
 //=============================================================================
 
-list<int> SMESH_Mesh::GetGroupIds()
+list<int> SMESH_Mesh::GetGroupIds() const
 {
   list<int> anIds;
   for ( map<int, SMESH_Group*>::const_iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ )
 {
   list<int> anIds;
   for ( map<int, SMESH_Group*>::const_iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ )
@@ -1282,279 +1286,6 @@ void SMESH_Mesh::RemoveGroup (const int theGroupID)
   _mapGroup.erase (theGroupID);
 }
 
   _mapGroup.erase (theGroupID);
 }
 
-//=============================================================================
-/*!
- *  IsLocal1DHypothesis
- *  Returns a local 1D hypothesis used for theEdge
- */
-//=============================================================================
-const SMESH_Hypothesis* SMESH_Mesh::IsLocal1DHypothesis (const TopoDS_Shape& theEdge)
-{
-  SMESH_HypoFilter hypo ( SMESH_HypoFilter::HasDim( 1 ));
-  hypo.AndNot( hypo.IsAlgo() ).AndNot( hypo.IsAssignedTo( GetMeshDS()->ShapeToMesh() ));
-
-  return GetHypothesis( theEdge, hypo, true );
-}
-
-//=============================================================================
-/*!
- *  IsPropagationHypothesis
- */
-//=============================================================================
-bool SMESH_Mesh::IsPropagationHypothesis (const TopoDS_Shape& theEdge)
-{
-  return _mapPropagationChains.Contains(theEdge);
-}
-
-//=============================================================================
-/*!
- *  IsPropagatedHypothesis
- */
-//=============================================================================
-bool SMESH_Mesh::IsPropagatedHypothesis (const TopoDS_Shape& theEdge,
-                                         TopoDS_Shape&       theMainEdge)
-{
-  int nbChains = _mapPropagationChains.Extent();
-  for (int i = 1; i <= nbChains; i++) {
-    //const TopTools_IndexedMapOfShape& aChain = _mapPropagationChains.FindFromIndex(i);
-    const SMESH_IndexedMapOfShape& aChain = _mapPropagationChains.FindFromIndex(i);
-    if (aChain.Contains(theEdge)) {
-      theMainEdge = _mapPropagationChains.FindKey(i);
-      return true;
-    }
-  }
-
-  return false;
-}
-//=============================================================================
-/*!
- *  IsReversedInChain
- */
-//=============================================================================
-
-bool SMESH_Mesh::IsReversedInChain (const TopoDS_Shape& theEdge,
-                                    const TopoDS_Shape& theMainEdge)
-{
-  if ( !theMainEdge.IsNull() && !theEdge.IsNull() &&
-      _mapPropagationChains.Contains( theMainEdge ))
-  {
-    const SMESH_IndexedMapOfShape& aChain =
-      _mapPropagationChains.FindFromKey( theMainEdge );
-    int index = aChain.FindIndex( theEdge );
-    if ( index )
-      return aChain(index).Orientation() == TopAbs_REVERSED;
-  }
-  return false;
-}
-
-//=============================================================================
-/*!
- *  CleanMeshOnPropagationChain
- */
-//=============================================================================
-void SMESH_Mesh::CleanMeshOnPropagationChain (const TopoDS_Shape& theMainEdge)
-{
-  const SMESH_IndexedMapOfShape& aChain = _mapPropagationChains.FindFromKey(theMainEdge);
-  int i, nbEdges = aChain.Extent();
-  for (i = 1; i <= nbEdges; i++) {
-    TopoDS_Shape anEdge = aChain.FindKey(i);
-    SMESH_subMesh *subMesh = GetSubMesh(anEdge);
-    SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS();
-    if (subMeshDS && subMeshDS->NbElements() > 0) {
-      subMesh->ComputeStateEngine(SMESH_subMesh::CLEAN);
-    }
-  }
-}
-
-//=============================================================================
-/*!
- *  RebuildPropagationChains
- *  Rebuild all existing propagation chains.
- *  Have to be used, if 1D hypothesis have been assigned/removed to/from any edge
- */
-//=============================================================================
-bool SMESH_Mesh::RebuildPropagationChains()
-{
-  bool ret = true;
-
-  // Clean all chains, because they can be not up-to-date
-  int i, nbChains = _mapPropagationChains.Extent();
-  for (i = 1; i <= nbChains; i++) {
-    TopoDS_Shape aMainEdge = _mapPropagationChains.FindKey(i);
-    CleanMeshOnPropagationChain(aMainEdge);
-    _mapPropagationChains.ChangeFromIndex(i).Clear();
-  }
-
-  // Build all chains
-  for (i = 1; i <= nbChains; i++) {
-    TopoDS_Shape aMainEdge = _mapPropagationChains.FindKey(i);
-    if (!BuildPropagationChain(aMainEdge))
-      ret = false;
-    CleanMeshOnPropagationChain(aMainEdge);
-  }
-
-  return ret;
-}
-
-//=============================================================================
-/*!
- *  RemovePropagationChain
- *  Have to be used, if Propagation hypothesis is removed from <theMainEdge>
- */
-//=============================================================================
-bool SMESH_Mesh::RemovePropagationChain (const TopoDS_Shape& theMainEdge)
-{
-  if (!_mapPropagationChains.Contains(theMainEdge))
-    return false;
-
-  // Clean mesh elements and nodes, built on the chain
-  CleanMeshOnPropagationChain(theMainEdge);
-
-  // Clean the chain
-  _mapPropagationChains.ChangeFromKey(theMainEdge).Clear();
-
-  // Remove the chain from the map
-  int i = _mapPropagationChains.FindIndex(theMainEdge);
-  if ( i == _mapPropagationChains.Extent() )
-    _mapPropagationChains.RemoveLast();
-  else {
-    TopoDS_Vertex anEmptyShape;
-    BRep_Builder BB;
-    BB.MakeVertex(anEmptyShape, gp_Pnt(0,0,0), 0.1);
-    SMESH_IndexedMapOfShape anEmptyMap;
-    _mapPropagationChains.Substitute(i, anEmptyShape, anEmptyMap);
-  }
-
-  return true;
-}
-
-//=============================================================================
-/*!
- *  BuildPropagationChain
- */
-//=============================================================================
-bool SMESH_Mesh::BuildPropagationChain (const TopoDS_Shape& theMainEdge)
-{
-  if (theMainEdge.ShapeType() != TopAbs_EDGE) return true;
-
-  // Add new chain, if there is no
-  if (!_mapPropagationChains.Contains(theMainEdge)) {
-    SMESH_IndexedMapOfShape aNewChain;
-    _mapPropagationChains.Add(theMainEdge, aNewChain);
-  }
-
-  // Check presence of 1D hypothesis to be propagated
-  const SMESH_Hypothesis* aMainHyp = IsLocal1DHypothesis(theMainEdge);
-  if (!aMainHyp) {
-    MESSAGE("Warning: There is no 1D hypothesis to propagate. Please, assign.");
-    return true;
-  }
-
-  // Edges, on which the 1D hypothesis will be propagated from <theMainEdge>
-  SMESH_IndexedMapOfShape& aChain = _mapPropagationChains.ChangeFromKey(theMainEdge);
-  if (aChain.Extent() > 0) {
-    CleanMeshOnPropagationChain(theMainEdge);
-    aChain.Clear();
-  }
-
-  // At first put <theMainEdge> in the chain
-  aChain.Add(theMainEdge);
-
-  // List of edges, added to chain on the previous cycle pass
-  TopTools_ListOfShape listPrevEdges;
-  listPrevEdges.Append(theMainEdge.Oriented( TopAbs_FORWARD ));
-
-//   5____4____3____4____5____6
-//   |    |    |    |    |    |
-//   |    |    |    |    |    |
-//   4____3____2____3____4____5
-//   |    |    |    |    |    |      Number in the each knot of
-//   |    |    |    |    |    |      grid indicates cycle pass,
-//   3____2____1____2____3____4      on which corresponding edge
-//   |    |    |    |    |    |      (perpendicular to the plane
-//   |    |    |    |    |    |      of view) will be found.
-//   2____1____0____1____2____3
-//   |    |    |    |    |    |
-//   |    |    |    |    |    |
-//   3____2____1____2____3____4
-
-  // Collect all edges pass by pass
-  while (listPrevEdges.Extent() > 0) {
-    // List of edges, added to chain on this cycle pass
-    TopTools_ListOfShape listCurEdges;
-
-    // Find the next portion of edges
-    TopTools_ListIteratorOfListOfShape itE (listPrevEdges);
-    for (; itE.More(); itE.Next()) {
-      TopoDS_Shape anE = itE.Value();
-
-      // Iterate on faces, having edge <anE>
-      TopTools_ListIteratorOfListOfShape itA (GetAncestors(anE));
-      for (; itA.More(); itA.Next()) {
-        TopoDS_Shape aW = itA.Value();
-
-        // There are objects of different type among the ancestors of edge
-        if (aW.ShapeType() == TopAbs_WIRE) {
-          TopoDS_Shape anOppE;
-
-          BRepTools_WireExplorer aWE (TopoDS::Wire(aW));
-          Standard_Integer nb = 1, found = 0;
-          TopTools_Array1OfShape anEdges (1,4);
-          for (; aWE.More(); aWE.Next(), nb++) {
-            if (nb > 4) {
-              found = 0;
-              break;
-            }
-            anEdges(nb) = aWE.Current();
-            if (!_mapAncestors.Contains(anEdges(nb))) {
-              MESSAGE("WIRE EXPLORER HAVE GIVEN AN INVALID EDGE !!!");
-              break;
-            }
-            if (anEdges(nb).IsSame(anE)) found = nb;
-          }
-
-          if (nb == 5 && found > 0) {
-            // Quadrangle face found, get an opposite edge
-            Standard_Integer opp = found + 2;
-            if (opp > 4) opp -= 4;
-            anOppE = anEdges(opp);
-
-            // add anOppE to aChain if ...
-            if (!aChain.Contains(anOppE)) { // ... anOppE is not in aChain
-              if (!IsLocal1DHypothesis(anOppE)) { // ... no other 1d hyp on anOppE
-                TopoDS_Shape aMainEdgeForOppEdge; // ... no other hyp is propagated to anOppE
-                if (!IsPropagatedHypothesis(anOppE, aMainEdgeForOppEdge))
-                {
-                  // Add found edge to the chain oriented so that to
-                  // have it co-directed with a forward MainEdge
-                  TopAbs_Orientation ori = anE.Orientation();
-                  if ( anEdges(opp).Orientation() == anEdges(found).Orientation() )
-                    ori = TopAbs::Reverse( ori );
-                  anOppE.Orientation( ori );
-                  aChain.Add(anOppE);
-                  listCurEdges.Append(anOppE);
-                }
-                else {
-                  // Collision!
-                  MESSAGE("Error: Collision between propagated hypotheses");
-                  CleanMeshOnPropagationChain(theMainEdge);
-                  aChain.Clear();
-                  return ( aMainHyp == IsLocal1DHypothesis(aMainEdgeForOppEdge) );
-                }
-              }
-            }
-          } // if (nb == 5 && found > 0)
-        } // if (aF.ShapeType() == TopAbs_WIRE)
-      } // for (; itF.More(); itF.Next())
-    } // for (; itE.More(); itE.Next())
-
-    listPrevEdges = listCurEdges;
-  } // while (listPrevEdges.Extent() > 0)
-
-  CleanMeshOnPropagationChain(theMainEdge);
-  return true;
-}
-
 //=======================================================================
 //function : GetAncestors
 //purpose  : return list of ancestors of theSubShape in the order
 //=======================================================================
 //function : GetAncestors
 //purpose  : return list of ancestors of theSubShape in the order
@@ -1574,56 +1305,70 @@ const TopTools_ListOfShape& SMESH_Mesh::GetAncestors(const TopoDS_Shape& theS) c
 //function : Dump
 //purpose  : dumps contents of mesh to stream [ debug purposes ]
 //=======================================================================
 //function : Dump
 //purpose  : dumps contents of mesh to stream [ debug purposes ]
 //=======================================================================
+
 ostream& SMESH_Mesh::Dump(ostream& save)
 {
 ostream& SMESH_Mesh::Dump(ostream& save)
 {
-  save << "========================== Dump contents of mesh ==========================" << endl;
-  save << "1) Total number of nodes:     " << NbNodes() << endl;
-  save << "2) Total number of edges:     " << NbEdges() << endl;
-  save << "3) Total number of faces:     " << NbFaces() << endl;
-  if ( NbFaces() > 0 ) {
-    int nb3 = NbTriangles();
-    int nb4 = NbQuadrangles();
-    save << "3.1.) Number of triangles:    " << nb3 << endl;
-    save << "3.2.) Number of quadrangles:  " << nb4 << endl;
-    if ( nb3 + nb4 !=  NbFaces() ) {
-      map<int,int> myFaceMap;
-      SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator();
-      while( itFaces->more( ) ) {
-       int nbNodes = itFaces->next()->NbNodes();
-       if ( myFaceMap.find( nbNodes ) == myFaceMap.end() )
-         myFaceMap[ nbNodes ] = 0;
-       myFaceMap[ nbNodes ] = myFaceMap[ nbNodes ] + 1;
+  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 polyhedrons:\t" << NbPolyhedrons() << endl << endl;
+  for ( int isQuadratic = 0; isQuadratic < 2; ++isQuadratic )
+  {
+    string orderStr = isQuadratic ? "quadratic" : "linear";
+    SMDSAbs_ElementOrder order  = isQuadratic ? ORDER_QUADRATIC : ORDER_LINEAR;
+
+    save << ++clause << ") Total number of " << orderStr << " edges:\t" << NbEdges(order) << endl;
+    save << ++clause << ") Total number of " << orderStr << " faces:\t" << NbFaces(order) << endl;
+    if ( NbFaces(order) > 0 ) {
+      int nb3 = NbTriangles(order);
+      int nb4 = NbQuadrangles(order);
+      save << clause << ".1) Number of " << orderStr << " triangles:  \t" << nb3 << endl;
+      save << clause << ".2) Number of " << orderStr << " quadrangles:\t" << nb4 << endl;
+      if ( nb3 + nb4 !=  NbFaces(order) ) {
+        map<int,int> myFaceMap;
+        SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator();
+        while( itFaces->more( ) ) {
+          int nbNodes = itFaces->next()->NbNodes();
+          if ( myFaceMap.find( nbNodes ) == myFaceMap.end() )
+            myFaceMap[ nbNodes ] = 0;
+          myFaceMap[ nbNodes ] = myFaceMap[ nbNodes ] + 1;
+        }
+        save << clause << ".3) Faces in detail: " << endl;
+        map <int,int>::iterator itF;
+        for (itF = myFaceMap.begin(); itF != myFaceMap.end(); itF++)
+          save << "--> nb nodes: " << itF->first << " - nb elemens:\t" << itF->second << endl;
       }
       }
-      save << "3.3.) Faces in detail: " << endl;
-      map <int,int>::iterator itF;
-      for (itF = myFaceMap.begin(); itF != myFaceMap.end(); itF++)
-       save << "--> nb nodes: " << itF->first << " - nb elemens: " << itF->second << endl;
     }
     }
-  }
-  save << "4) Total number of volumes:   " << NbVolumes() << endl;
-  if ( NbVolumes() > 0 ) {
-    int nb8 = NbHexas();
-    int nb4 = NbTetras();
-    int nb5 = NbPyramids();
-    int nb6 = NbPrisms();
-    save << "4.1.) Number of hexahedrons:  " << nb8 << endl;
-    save << "4.2.) Number of tetrahedrons: " << nb4 << endl;
-    save << "4.3.) Number of prisms:       " << nb6 << endl;
-    save << "4.4.) Number of pyramides:    " << nb5 << endl;
-    if ( nb8 + nb4 + nb5 + nb6 != NbVolumes() ) {
-      map<int,int> myVolumesMap;
-      SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
-      while( itVolumes->more( ) ) {
-       int nbNodes = itVolumes->next()->NbNodes();
-       if ( myVolumesMap.find( nbNodes ) == myVolumesMap.end() )
-         myVolumesMap[ nbNodes ] = 0;
-       myVolumesMap[ nbNodes ] = myVolumesMap[ nbNodes ] + 1;
+    save << ++clause << ") Total number of " << orderStr << " volumes:\t" << NbVolumes(order) << endl;
+    if ( NbVolumes(order) > 0 ) {
+      int nb8 = NbHexas(order);
+      int nb4 = NbTetras(order);
+      int nb5 = NbPyramids(order);
+      int nb6 = NbPrisms(order);
+      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;
+      if ( nb8 + nb4 + nb5 + nb6 != NbVolumes(order) ) {
+        map<int,int> myVolumesMap;
+        SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
+        while( itVolumes->more( ) ) {
+          int nbNodes = itVolumes->next()->NbNodes();
+          if ( myVolumesMap.find( nbNodes ) == myVolumesMap.end() )
+            myVolumesMap[ nbNodes ] = 0;
+          myVolumesMap[ nbNodes ] = myVolumesMap[ nbNodes ] + 1;
+        }
+        save << clause << ".5) Volumes in detail: " << endl;
+        map <int,int>::iterator itV;
+        for (itV = myVolumesMap.begin(); itV != myVolumesMap.end(); itV++)
+          save << "--> nb nodes: " << itV->first << " - nb elemens:\t" << itV->second << endl;
       }
       }
-      save << "4.5.) Volumes in detail: " << endl;
-      map <int,int>::iterator itV;
-      for (itV = myVolumesMap.begin(); itV != myVolumesMap.end(); itV++)
-       save << "--> nb nodes: " << itV->first << " - nb elemens: " << itV->second << endl;
     }
     }
+    save << endl;
   }
   save << "===========================================================================" << endl;
   return save;
   }
   save << "===========================================================================" << endl;
   return save;
@@ -1633,6 +1378,7 @@ ostream& SMESH_Mesh::Dump(ostream& save)
 //function : GetElementType
 //purpose  : Returns type of mesh element with certain id
 //=======================================================================
 //function : GetElementType
 //purpose  : Returns type of mesh element with certain id
 //=======================================================================
+
 SMDSAbs_ElementType SMESH_Mesh::GetElementType( const int id, const bool iselem )
 {
   return _myMeshDS->GetElementType( id, iselem );
 SMDSAbs_ElementType SMESH_Mesh::GetElementType( const int id, const bool iselem )
 {
   return _myMeshDS->GetElementType( id, iselem );