Salome HOME
#17636 [CEA 17369] Extrusion by normal: along average normal option issue
[modules/smesh.git] / src / SMESH / SMESH_subMesh.cxx
index 05800491ba7ffb27dbff708c1a3f9ba00cea635d..f58cbe5b3456d37bfeeb99d8da57cc1b57dfd9c0 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2019  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -201,7 +201,7 @@ SMESH_Algo* SMESH_subMesh::GetAlgo() const
   if ( !_algo )
   {
     SMESH_subMesh* me = const_cast< SMESH_subMesh* >( this );
-    me->_algo = _father->GetGen()->GetAlgo( me );
+    me->_algo = _father->GetGen()->GetAlgo( me, & me->_algoShape );
   }
   return _algo;
 }
@@ -365,7 +365,7 @@ int SMESH_subMesh::computeCost() const
  */
 //=============================================================================
 
-const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn()
+const std::map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn()
 {
   if ( _dependenceAnalysed || !_father->HasShapeToMesh() )
     return _mapDepend;
@@ -878,7 +878,10 @@ SMESH_Hypothesis::Hypothesis_Status
         const SMESH_Hypothesis * prevAlgo = _father->GetHypothesis( this, f, true );
         if (prevAlgo &&
             string( algo->GetName()) != prevAlgo->GetName())
-          modifiedHyp = true;
+        {
+          oldAlgoState = NO_ALGO; // force setting event listener (#16648)
+          modifiedHyp  = true;
+        }
       }
       else
         setAlgoState(MISSING_HYP);
@@ -1293,40 +1296,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
-        bool rev = true;
-        SMDS_ElemIteratorPtr ite = subMeshDS->GetElements( rev );
-        const SMDS_MeshElement * lastElem = ite->next();
-        rev = ( lastElem->GetID() == meshDS->MaxElementID() );
-        if ( !rev )
-          ite = subMeshDS->GetElements( rev );
-        else
-          meshDS->RemoveFreeElement( lastElem, subMeshDS );
-        while (ite->more()) {
-          const SMDS_MeshElement * elt = ite->next();
-          meshDS->RemoveFreeElement( elt, subMeshDS );
-        }
-      }
+        for ( SMDS_ElemIteratorPtr ite = subMeshDS->GetElements(); ite->more(); )
+          meshDS->RemoveFreeElement( ite->next(), subMeshDS );
+
       int nbNodes = subMeshDS->NbNodes();
       if ( nbNodes > 0 )
-      {
-        bool rev = true;
-        SMDS_NodeIteratorPtr itn = subMeshDS->GetNodes( rev );
-        const SMDS_MeshNode * lastNode = itn->next();
-        rev = ( lastNode->GetID() == meshDS->MaxNodeID() );
-        if ( !rev )
-          itn = subMeshDS->GetNodes( rev );
-        else
-          meshDS->RemoveNode( lastNode );
-        while (itn->more()) {
+        for ( SMDS_NodeIteratorPtr itn = subMeshDS->GetNodes(); itn->more() ; )
+        {
           const SMDS_MeshNode * node = itn->next();
           if ( node->NbInverseElements() == 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();
     }
   }
@@ -1704,6 +1686,8 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event)
           else
             updateDependantsState( SUBMESH_COMPUTED );
         }
+        // let algo clear its data gathered while algo->Compute()
+        algo->CheckHypothesis((*_father), _subShape, hyp_status);
       }
       break;
     case COMPUTE_CANCELED:               // nothing to do
@@ -2136,8 +2120,9 @@ TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * theGen,
     return _subShape;
 
   const bool skipAuxHyps = false;
-  list<const SMESHDS_Hypothesis*> aUsedHyp =
+  list<const SMESHDS_Hypothesis*> usedHyps =
     theAlgo->GetUsedHypothesis( *_father, _subShape, skipAuxHyps ); // copy
+  std::list < TopoDS_Shape >  assiShapes = theAlgo->GetAssignedShapes();
 
   // put in a compound all shapes with the same hypothesis assigned
   // and a good ComputeState
@@ -2164,7 +2149,9 @@ TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * theGen,
     {
       SMESH_Algo* anAlgo = subMesh->GetAlgo();
       if (( anAlgo->IsSameName( *theAlgo )) && // same algo
-          ( anAlgo->GetUsedHypothesis( *_father, S, skipAuxHyps ) == aUsedHyp )) // same hyps
+          ( anAlgo->GetUsedHypothesis( *_father, S, skipAuxHyps ) == usedHyps ) && // same hyps
+          ( anAlgo->GetAssignedShapes() == assiShapes ) && // on same sub-shapes
+          ( _algoShape == subMesh->_algoShape ))
       {
         aBuilder.Add( aCompound, S );
         if ( !subMesh->SubMeshesComputed() )
@@ -2297,9 +2284,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
   {
@@ -2307,6 +2294,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() )
@@ -2470,7 +2458,8 @@ void SMESH_subMesh::loadDependentMeshes()
 {
   list< OwnListenerData >::iterator d;
   for ( d = _ownListeners.begin(); d != _ownListeners.end(); ++d )
-    if ( _father != d->mySubMesh->_father )
+    if ( _father != d->mySubMesh->_father &&
+         _father->FindMesh( d->myMeshID ))
       d->mySubMesh->_father->Load();
 
   // map< EventListener*, EventListenerData* >::iterator l_d = _eventListeners.begin();
@@ -2569,9 +2558,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
  */
 //================================================================================
 
@@ -2612,8 +2601,13 @@ const std::vector< SMESH_subMesh * > & SMESH_subMesh::GetAncestors() const
     SMESH_subMesh* me = const_cast< SMESH_subMesh* >( this );
     me->_ancestors.reserve( ancShapes.Extent() );
 
+    // assure that all sub-meshes exist
+    TopoDS_Shape mainShape = _father->GetShapeToMesh();
+    if ( !mainShape.IsNull() )
+      _father->GetSubMesh( mainShape )->DependsOn();
+
     TopTools_MapOfShape map;
-   
+
     for ( TopTools_ListIteratorOfListOfShape it( ancShapes ); it.More(); it.Next() )
       if ( SMESH_subMesh* sm = _father->GetSubMeshContaining( it.Value() ))
         if ( map.Add( it.Value() ))