Salome HOME
54355: 'Compute' button is absent for 'Number of the double nodes' value in 'Mesh...
[modules/smesh.git] / src / SMESH / SMESH_subMesh.cxx
index fdea4fed2434d9910a27945657cc74a3a41f7d0c..5b5de318b6a1d46e29ff7f5990f9e62222989fef 100644 (file)
@@ -20,7 +20,7 @@
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
-//  SMESH SMESH : implementaion of SMESH idl descriptions
+//  SMESH SMESH : implementation of SMESH idl descriptions
 //  File   : SMESH_subMesh.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
@@ -38,8 +38,6 @@
 #include "SMESH_MesherHelper.hxx"
 #include "SMESH_subMeshEventListener.hxx"
 
-#include <Basics_OCCTVersion.hxx>
-
 #include "utilities.h"
 #include "OpUtil.hxx"
 #include "Basics_Utils.hxx"
 
 using namespace std;
 
+#ifdef _DEBUG_
+// enable printing algo + shape id + hypo used while meshing
+//#define PRINT_WHO_COMPUTE_WHAT
+#endif
+
 //=============================================================================
 /*!
  * \brief Allocate some memory at construction and release it at destruction.
@@ -488,7 +491,7 @@ const TopoDS_Shape & SMESH_subMesh::GetSubShape() const
 //=======================================================================
 //function : CanAddHypothesis
 //purpose  : return true if theHypothesis can be attached to me:
-//           its dimention is checked
+//           its dimension is checked
 //=======================================================================
 
 bool SMESH_subMesh::CanAddHypothesis(const SMESH_Hypothesis* theHypothesis) const
@@ -509,12 +512,25 @@ bool SMESH_subMesh::CanAddHypothesis(const SMESH_Hypothesis* theHypothesis) cons
 }
 
 //=======================================================================
-//function : IsApplicableHypotesis
-//purpose  :
+//function : IsApplicableHypothesis
+//purpose  : check if this sub-mesh can be computed using a hypothesis
+//=======================================================================
+
+bool SMESH_subMesh::IsApplicableHypothesis(const SMESH_Hypothesis* theHypothesis) const
+{
+  if ( !_father->HasShapeToMesh() && _subShape.ShapeType() == TopAbs_SOLID )
+    return true; // true for the PseudoShape
+
+  return IsApplicableHypothesis( theHypothesis, _subShape.ShapeType() );
+}
+
+//=======================================================================
+//function : IsApplicableHypothesis
+//purpose  : compare shape type and hypothesis type
 //=======================================================================
 
-bool SMESH_subMesh::IsApplicableHypotesis(const SMESH_Hypothesis* theHypothesis,
-                                          const TopAbs_ShapeEnum  theShapeType)
+bool SMESH_subMesh::IsApplicableHypothesis(const SMESH_Hypothesis* theHypothesis,
+                                           const TopAbs_ShapeEnum  theShapeType)
 {
   if ( theHypothesis->GetType() > SMESHDS_Hypothesis::PARAM_ALGO)
   {
@@ -606,7 +622,7 @@ SMESH_Hypothesis::Hypothesis_Status
   bool modifiedHyp = (event == MODIF_HYP);  // if set to true, force event MODIF_ALGO_STATE
   SMESH_Algo* algoRequiringCleaning = 0;
 
-  bool isApplicableHyp = IsApplicableHypotesis( anHyp );
+  bool isApplicableHyp = IsApplicableHypothesis( anHyp );
 
   if (event == ADD_ALGO || event == ADD_FATHER_ALGO)
   {
@@ -628,7 +644,7 @@ SMESH_Hypothesis::Hypothesis_Status
       filter.Or( SMESH_HypoFilter::HasType( algo->GetType()+1 ));
       filter.Or( SMESH_HypoFilter::HasType( algo->GetType()+2 ));
       if ( SMESH_Algo * curAlgo = (SMESH_Algo*)_father->GetHypothesis( this, filter, true ))
-        if ( !curAlgo->NeedDiscreteBoundary() )
+        if ( !curAlgo->NeedDiscreteBoundary() && curAlgo != anHyp )
           algoRequiringCleaning = curAlgo;
     }
   }
@@ -1056,7 +1072,7 @@ bool SMESH_subMesh::IsConform(const SMESH_Algo* theAlgo)
   if ( !theAlgo ) return false;
 
   // Suppose that theAlgo is applicable to _subShape, do not check it here
-  //if ( !IsApplicableHypotesis( theAlgo )) return false;
+  //if ( !IsApplicableHypothesis( theAlgo )) return false;
 
   // check only algo that doesn't NeedDiscreteBoundary(): because mesh made
   // on a sub-shape will be ignored by theAlgo
@@ -1277,30 +1293,19 @@ static void cleanSubMesh( SMESH_subMesh * subMesh )
       SMESHDS_Mesh * meshDS = subMesh->GetFather()->GetMeshDS();
       int nbElems = subMeshDS->NbElements();
       if ( nbElems > 0 )
-      {
-        // start from elem with max ID to avoid filling the pool of IDs
-        const SMDS_MeshElement * lastElem = subMeshDS->GetElement( nbElems-1 );
-        bool rev = ( lastElem->GetID() == meshDS->MaxElementID() );
-        SMDS_ElemIteratorPtr ite = subMeshDS->GetElements( rev );
-        while (ite->more()) {
-          const SMDS_MeshElement * elt = ite->next();
-          meshDS->RemoveFreeElement(elt, 0);
-        }
-      }
+        for ( SMDS_ElemIteratorPtr ite = subMeshDS->GetElements(); ite->more(); )
+          meshDS->RemoveFreeElement( ite->next(), subMeshDS );
+
       int nbNodes = subMeshDS->NbNodes();
       if ( nbNodes > 0 )
-      {
-        const SMDS_MeshNode * lastNode = subMeshDS->GetNode( nbNodes-1 );
-        bool rev = ( lastNode->GetID() == meshDS->MaxNodeID() );
-        SMDS_NodeIteratorPtr itn = subMeshDS->GetNodes( rev );
-        while (itn->more()) {
+        for ( SMDS_NodeIteratorPtr itn = subMeshDS->GetNodes(); itn->more() ; )
+        {
           const SMDS_MeshNode * node = itn->next();
           if ( node->NbInverseElements() == 0 )
-            meshDS->RemoveFreeNode(node, 0);
+            meshDS->RemoveFreeNode( node, subMeshDS );
           else // for StdMeshers_CompositeSegment_1D: node in one submesh, edge in another
-            meshDS->RemoveNode(node);
+            meshDS->RemoveNode( node );
         }
-      }
       subMeshDS->Clear();
     }
   }
@@ -1426,6 +1431,31 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event)
           _computeState = READY_TO_COMPUTE;
       }
       break;
+
+    case COMPUTE_NOGEOM:  // no geometry; can be several algos
+      if ( !_father->HasShapeToMesh() )
+      {
+        algo = GetAlgo(); // current algo
+        if ( algo )
+        {
+          // apply algos in the order of increasing dimension
+          std::list< const SMESHDS_Hypothesis * > algos = _father->GetHypothesisList( _subShape );
+          for ( int t = SMESHDS_Hypothesis::ALGO_1D; t <= SMESHDS_Hypothesis::ALGO_3D; ++t )
+          {
+            std::list<const SMESHDS_Hypothesis *>::iterator al = algos.begin();
+            for ( ; al != algos.end(); ++al )
+              if ( (*al)->GetType() == t )
+              {
+                _algo = (SMESH_Algo*) *al;
+                _computeState = READY_TO_COMPUTE;
+                if ( !ComputeStateEngine( COMPUTE ))
+                  break;
+              }
+          }
+          _algo = algo; // restore
+        }
+        break;
+      }
     case COMPUTE:
     case COMPUTE_SUBMESH:
       {
@@ -1565,6 +1595,23 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event)
                    !algo->isDegenerated( TopoDS::Edge( subS.Current() ))))
               ret = false;
         }
+#ifdef PRINT_WHO_COMPUTE_WHAT
+        for (subS.ReInit(); subS.More(); subS.Next())
+        {
+          const std::list <const SMESHDS_Hypothesis *> & hyps =
+            _algo->GetUsedHypothesis( *_father, _subShape );
+          SMESH_Comment hypStr;
+          if ( !hyps.empty() )
+          {
+            hypStr << hyps.front()->GetName() << " ";
+            ((SMESHDS_Hypothesis*)hyps.front())->SaveTo( hypStr.Stream() );
+            hypStr << " ";
+          }
+          cout << _algo->GetName()
+               << " " << _father->GetSubMesh( subS.Current() )->GetId()
+               << " " << hypStr << endl;
+        }
+#endif
         // Set _computeError
         if ( !ret && !isComputeErrorSet )
         {
@@ -1698,7 +1745,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event)
     case COMPUTE_CANCELED:      // nothing to do
       break;
     case CLEAN:
-      cleanDependants();  // clean sub-meshes, dependant on this one, with event CLEAN
+      cleanDependants();  // clean sub-meshes, dependent on this one, with event CLEAN
       removeSubMeshElementsAndNodes();
       _computeState = NOT_READY;
       if ( _algoState == HYP_OK )
@@ -2139,16 +2186,14 @@ const SMESH_Hypothesis* SMESH_subMesh::getSimilarAttached(const TopoDS_Shape&
 }
 
 //=======================================================================
-//function : CheckConcurentHypothesis
+//function : CheckConcurrentHypothesis
 //purpose  : check if there are several applicable hypothesis attached to
 //           ancestors
 //=======================================================================
 
 SMESH_Hypothesis::Hypothesis_Status
-  SMESH_subMesh::CheckConcurentHypothesis (const int theHypType)
+  SMESH_subMesh::CheckConcurrentHypothesis (const int theHypType)
 {
-  MESSAGE ("SMESH_subMesh::CheckConcurentHypothesis");
-
   // is there local hypothesis on me?
   if ( getSimilarAttached( _subShape, 0, theHypType ) )
     return SMESH_Hypothesis::HYP_OK;
@@ -2169,7 +2214,7 @@ SMESH_Hypothesis::Hypothesis_Status
         aPrevHyp     = hyp;
       }
       else if ( aPrevWithHyp.ShapeType() == ancestor.ShapeType() && aPrevHyp != hyp )
-        return SMESH_Hypothesis::HYP_CONCURENT;
+        return SMESH_Hypothesis::HYP_CONCURRENT;
       else
         return SMESH_Hypothesis::HYP_OK;
     }
@@ -2231,9 +2276,9 @@ void SMESH_subMesh::setEventListener(EventListener*     listener,
     _eventListeners.find( listener );
   if ( l_d != _eventListeners.end() ) {
     EventListenerData* curData = l_d->second;
+    l_d->second = data;
     if ( curData && curData != data && curData->IsDeletable() )
       delete curData;
-    l_d->second = data;
   }
   else
   {
@@ -2241,6 +2286,7 @@ void SMESH_subMesh::setEventListener(EventListener*     listener,
       if ( listener->GetName() == l_d->first->GetName() )
       {
         EventListenerData* curData = l_d->second;
+        l_d->second = 0;
         if ( curData && curData != data && curData->IsDeletable() )
           delete curData;
         if ( l_d->first != listener && l_d->first->IsDeletable() )
@@ -2318,7 +2364,7 @@ EventListenerData* SMESH_subMesh::GetEventListenerData(const string& listenerNam
 
 //================================================================================
 /*!
- * \brief Notify stored event listeners on the occured event
+ * \brief Notify stored event listeners on the occurred event
  * \param event - algo_event or compute_event itself
  * \param eventType - algo_event or compute_event
  * \param hyp - hypothesis, if eventType is algo_event
@@ -2424,7 +2470,7 @@ void SMESH_subMesh::loadDependentMeshes()
  * \brief Do something on a certain event
  * \param event - algo_event or compute_event itself
  * \param eventType - algo_event or compute_event
- * \param subMesh - the submesh where the event occures
+ * \param subMesh - the submesh where the event occurs
  * \param data - listener data stored in the subMesh
  * \param hyp - hypothesis, if eventType is algo_event
  * 
@@ -2503,9 +2549,9 @@ namespace {
 
 //================================================================================
 /*!
- * \brief  Return iterator on the submeshes this one depends on
 * \param includeSelf - this submesh to be returned also
 * \param reverse - if true, complex shape submeshes go first
+ * \brief Return iterator on the submeshes this one depends on
 \param includeSelf - this submesh to be returned also
 \param reverse - if true, complex shape submeshes go first
  */
 //================================================================================
 
@@ -2547,7 +2593,10 @@ const std::vector< SMESH_subMesh * > & SMESH_subMesh::GetAncestors() const
     me->_ancestors.reserve( ancShapes.Extent() );
 
     TopTools_MapOfShape map;
-   
+
+    // assure that all sub-meshes exist
+    _father->GetSubMesh( _father->GetShapeToMesh() )->DependsOn();
+
     for ( TopTools_ListIteratorOfListOfShape it( ancShapes ); it.More(); it.Next() )
       if ( SMESH_subMesh* sm = _father->GetSubMeshContaining( it.Value() ))
         if ( map.Add( it.Value() ))