Salome HOME
23092: EDF 10836 SMESH: UseExisting2DElements fails when geometry contains more than...
[modules/smesh.git] / src / SMESH / SMESH_subMesh.cxx
index 5edc28da04745a77f3c807de0a3d1592d366e241..3745a2b77afe3dcce5911f5de6506c17cef6f2fc 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -670,11 +670,17 @@ bool SMESH_subMesh::IsApplicableHypotesis(const SMESH_Hypothesis* theHypothesis,
   return false;
 }
 
   return false;
 }
 
-//=============================================================================
+//================================================================================
 /*!
 /*!
- *
+ * \brief Treats modification of hypotheses definition
+ *  \param [in] event - what happens
+ *  \param [in] anHyp - a hypothesis
+ *  \return SMESH_Hypothesis::Hypothesis_Status - a treatment result.
+ * 
+ * Optional description of a problematic situation (if any) can be retrieved
+ * via GetComputeError().
  */
  */
-//=============================================================================
+//================================================================================
 
 SMESH_Hypothesis::Hypothesis_Status
   SMESH_subMesh::AlgoStateEngine(int event, SMESH_Hypothesis * anHyp)
 
 SMESH_Hypothesis::Hypothesis_Status
   SMESH_subMesh::AlgoStateEngine(int event, SMESH_Hypothesis * anHyp)
@@ -753,7 +759,7 @@ SMESH_Hypothesis::Hypothesis_Status
     if ( ! CanAddHypothesis( anHyp )) // check dimension
       return SMESH_Hypothesis::HYP_BAD_DIM;
 
     if ( ! CanAddHypothesis( anHyp )) // check dimension
       return SMESH_Hypothesis::HYP_BAD_DIM;
 
-    if ( /*!anHyp->IsAuxiliary() &&*/ getSimilarAttached( _subShape, anHyp ) )
+    if ( !anHyp->IsAuxiliary() && getSimilarAttached( _subShape, anHyp ) )
       return SMESH_Hypothesis::HYP_ALREADY_EXIST;
 
     if ( !meshDS->AddHypothesis(_subShape, anHyp))
       return SMESH_Hypothesis::HYP_ALREADY_EXIST;
 
     if ( !meshDS->AddHypothesis(_subShape, anHyp))
@@ -782,6 +788,9 @@ SMESH_Hypothesis::Hypothesis_Status
   if (!isApplicableHyp)
     return ret; // not applicable hypotheses do not change algo state
 
   if (!isApplicableHyp)
     return ret; // not applicable hypotheses do not change algo state
 
+  if (( algo = GetAlgo()))
+    algo->InitComputeError();
+
   switch (_algoState)
   {
 
   switch (_algoState)
   {
 
@@ -946,7 +955,7 @@ SMESH_Hypothesis::Hypothesis_Status
           // ret should be fatal: anHyp was not added
           ret = SMESH_Hypothesis::HYP_INCOMPATIBLE;
       }
           // ret should be fatal: anHyp was not added
           ret = SMESH_Hypothesis::HYP_INCOMPATIBLE;
       }
-      else if (!_father->IsUsedHypothesis(  anHyp, this ))
+      else if (!_father->IsUsedHypothesis( anHyp, this ))
         ret = SMESH_Hypothesis::HYP_INCOMPATIBLE;
 
       if (SMESH_Hypothesis::IsStatusFatal( ret ))
         ret = SMESH_Hypothesis::HYP_INCOMPATIBLE;
 
       if (SMESH_Hypothesis::IsStatusFatal( ret ))
@@ -1114,6 +1123,11 @@ SMESH_Hypothesis::Hypothesis_Status
     }
   }
 
     }
   }
 
+  if ( _algo ) { // get an error description set by _algo->CheckHypothesis()
+    _computeError = _algo->GetComputeError();
+    _algo->InitComputeError();
+  }
+
   bool stateChange = ( _algoState != oldAlgoState );
 
   if ( stateChange && _algoState == HYP_OK ) // hyp becomes OK
   bool stateChange = ( _algoState != oldAlgoState );
 
   if ( stateChange && _algoState == HYP_OK ) // hyp becomes OK
@@ -1141,8 +1155,8 @@ SMESH_Hypothesis::Hypothesis_Status
     ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE );
   }
 
     ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE );
   }
 
-  if (stateChange || modifiedHyp)
-    ComputeStateEngine(MODIF_ALGO_STATE);
+  if ( stateChange || modifiedHyp )
+    ComputeStateEngine( MODIF_ALGO_STATE );
 
   _realComputeCost = ( _algoState == HYP_OK ) ? computeCost() : 0;
 
 
   _realComputeCost = ( _algoState == HYP_OK ) ? computeCost() : 0;
 
@@ -1213,14 +1227,24 @@ void SMESH_subMesh::setAlgoState(algo_state state)
   _algoState = state;
 }
 
   _algoState = state;
 }
 
-//=============================================================================
+//================================================================================
 /*!
 /*!
+ * \brief Send an event to sub-meshes
+ *  \param [in] event - the event
+ *  \param [in] anHyp - an hypothesis
+ *  \param [in] exitOnFatal - to stop iteration on sub-meshes if a sub-mesh
+ *              reports a fatal result
+ *  \return SMESH_Hypothesis::Hypothesis_Status - the worst result
  *
  *
+ * Optional description of a problematic situation (if any) can be retrieved
+ * via GetComputeError().
  */
  */
-//=============================================================================
+//================================================================================
+
 SMESH_Hypothesis::Hypothesis_Status
 SMESH_Hypothesis::Hypothesis_Status
-  SMESH_subMesh::SubMeshesAlgoStateEngine(int event,
-                                          SMESH_Hypothesis * anHyp)
+  SMESH_subMesh::SubMeshesAlgoStateEngine(int                event,
+                                          SMESH_Hypothesis * anHyp,
+                                          bool               exitOnFatal)
 {
   SMESH_Hypothesis::Hypothesis_Status ret = SMESH_Hypothesis::HYP_OK;
   //EAP: a wire (dim==1) should notify edges (dim==1)
 {
   SMESH_Hypothesis::Hypothesis_Status ret = SMESH_Hypothesis::HYP_OK;
   //EAP: a wire (dim==1) should notify edges (dim==1)
@@ -1229,10 +1253,16 @@ SMESH_Hypothesis::Hypothesis_Status
   {
     SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false);
     while ( smIt->more() ) {
   {
     SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false);
     while ( smIt->more() ) {
-      SMESH_Hypothesis::Hypothesis_Status ret2 =
-        smIt->next()->AlgoStateEngine(event, anHyp);
+      SMESH_subMesh* sm = smIt->next();
+      SMESH_Hypothesis::Hypothesis_Status ret2 = sm->AlgoStateEngine(event, anHyp);
       if ( ret2 > ret )
       if ( ret2 > ret )
+      {
         ret = ret2;
         ret = ret2;
+        _computeError = sm->_computeError;
+        sm->_computeError.reset();
+        if ( exitOnFatal && SMESH_Hypothesis::IsStatusFatal( ret ))
+          break;
+      }
     }
   }
   return ret;
     }
   }
   return ret;
@@ -1831,10 +1861,13 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
       removeSubMeshElementsAndNodes();
       break;
     case SUBMESH_COMPUTED:      // allow retry compute
       removeSubMeshElementsAndNodes();
       break;
     case SUBMESH_COMPUTED:      // allow retry compute
-      if (_algoState == HYP_OK)
-        _computeState = READY_TO_COMPUTE;
-      else
-        _computeState = NOT_READY;
+      if ( IsEmpty() ) // 23061
+      {
+        if (_algoState == HYP_OK)
+          _computeState = READY_TO_COMPUTE;
+        else
+          _computeState = NOT_READY;
+      }
       break;
     case SUBMESH_RESTORED:
       ComputeSubMeshStateEngine( SUBMESH_RESTORED );
       break;
     case SUBMESH_RESTORED:
       ComputeSubMeshStateEngine( SUBMESH_RESTORED );
@@ -2118,9 +2151,9 @@ TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * theGen,
   if ( mainShape.IsSame( _subShape ))
     return _subShape;
 
   if ( mainShape.IsSame( _subShape ))
     return _subShape;
 
-  const bool ignoreAuxiliaryHyps = false;
+  const bool skipAuxHyps = false;
   list<const SMESHDS_Hypothesis*> aUsedHyp =
   list<const SMESHDS_Hypothesis*> aUsedHyp =
-    theAlgo->GetUsedHypothesis( *_father, _subShape, ignoreAuxiliaryHyps ); // copy
+    theAlgo->GetUsedHypothesis( *_father, _subShape, skipAuxHyps ); // copy
 
   // put in a compound all shapes with the same hypothesis assigned
   // and a good ComputeState
 
   // put in a compound all shapes with the same hypothesis assigned
   // and a good ComputeState
@@ -2131,11 +2164,13 @@ TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * theGen,
 
   theSubs.clear();
 
 
   theSubs.clear();
 
-  TopExp_Explorer anExplorer( mainShape, _subShape.ShapeType() );
-  for ( ; anExplorer.More(); anExplorer.Next() )
+  SMESH_subMeshIteratorPtr smIt = _father->GetSubMesh( mainShape )->getDependsOnIterator(false);
+  while ( smIt->more() )
   {
   {
-    const TopoDS_Shape& S = anExplorer.Current();
-    SMESH_subMesh* subMesh = _father->GetSubMesh( S );
+    SMESH_subMesh* subMesh = smIt->next();
+    const TopoDS_Shape&  S = subMesh->_subShape;
+    if ( S.ShapeType() != this->_subShape.ShapeType() )
+      continue;
     theSubs.push_back( subMesh );
     if ( subMesh == this )
     {
     theSubs.push_back( subMesh );
     if ( subMesh == this )
     {
@@ -2143,12 +2178,14 @@ TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * theGen,
     }
     else if ( subMesh->GetComputeState() == READY_TO_COMPUTE )
     {
     }
     else if ( subMesh->GetComputeState() == READY_TO_COMPUTE )
     {
-      SMESH_Algo* anAlgo = theGen->GetAlgo( subMesh );
-      if (strcmp( anAlgo->GetName(), theAlgo->GetName()) == 0 && // same algo
-          anAlgo->GetUsedHypothesis( *_father, S, ignoreAuxiliaryHyps ) == aUsedHyp) // same hyps
+      SMESH_Algo* anAlgo = subMesh->GetAlgo();
+      if (( anAlgo->IsSameName( *theAlgo )) && // same algo
+          ( anAlgo->GetUsedHypothesis( *_father, S, skipAuxHyps ) == aUsedHyp )) // same hyps
+      {
         aBuilder.Add( aCompound, S );
         aBuilder.Add( aCompound, S );
-      if ( !subMesh->SubMeshesComputed() )
-        theSubComputed = false;
+        if ( !subMesh->SubMeshesComputed() )
+          theSubComputed = false;
+      }
     }
   }
 
     }
   }
 
@@ -2433,9 +2470,8 @@ void SMESH_subMesh::deleteOwnListeners()
   list< OwnListenerData >::iterator d;
   for ( d = _ownListeners.begin(); d != _ownListeners.end(); ++d )
   {
   list< OwnListenerData >::iterator d;
   for ( d = _ownListeners.begin(); d != _ownListeners.end(); ++d )
   {
-    if ( !_father->MeshExists( d->myMeshID ))
-      continue;
-    if ( _father->GetId() == d->myMeshID && !_father->GetSubMeshContaining( d->mySubMeshID ))
+    SMESH_Mesh* mesh = _father->FindMesh( d->myMeshID );
+    if ( !mesh || !mesh->GetSubMeshContaining( d->mySubMeshID ))
       continue;
     d->mySubMesh->DeleteEventListener( d->myListener );
   }
       continue;
     d->mySubMesh->DeleteEventListener( d->myListener );
   }