Salome HOME
bos #26523 EDF 24234 - Viscous Layer
[modules/smesh.git] / src / SMESH / SMESH_subMesh.cxx
index e8a61f295e8675f80d042240b222e5d77b3c80f9..6975f958bb08a86ab917e34798312582229e5fe5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2021  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
@@ -110,6 +110,7 @@ SMESH_subMesh::SMESH_subMesh(int                  Id,
   }
   _computeCost = 0; // how costly is to compute this sub-mesh
   _realComputeCost = 0;
+  _allowedSubShapes = nullptr;
 }
 
 //=============================================================================
@@ -201,7 +202,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;
 }
@@ -271,6 +272,42 @@ bool SMESH_subMesh::IsMeshComputed() const
   return false;
 }
 
+//================================================================================
+/*!
+ * \brief Check if any upper level sub-shape is not computed.
+ *        Used to update a sub-mesh icon
+ */
+//================================================================================
+
+bool SMESH_subMesh::IsComputedPartially() const
+{
+  SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(/*includeSelf=*/true,
+                                                       /*SolidFirst=*/true);
+  bool allComputed = true;
+  TopAbs_ShapeEnum readyType = TopAbs_VERTEX; // max value
+  while ( smIt->more() && allComputed )
+  {
+    SMESH_subMesh* sm = smIt->next();
+
+    if ( sm->GetSubShape().ShapeType() > readyType )
+      break; // lower dimension -> stop
+    if ( sm->GetComputeState() != SMESH_subMesh::NOT_READY )
+      readyType = sm->GetSubShape().ShapeType();
+
+    switch ( sm->GetComputeState() )
+    {
+    case SMESH_subMesh::READY_TO_COMPUTE:
+    case SMESH_subMesh::FAILED_TO_COMPUTE:
+      allComputed = false;// sm->IsMeshComputed();
+      break;
+    case SMESH_subMesh::NOT_READY:
+    case SMESH_subMesh::COMPUTE_OK:
+      continue;
+    }
+  }
+  return !allComputed;
+}
+
 //=============================================================================
 /*!
  * Return true if all sub-meshes have been meshed
@@ -365,7 +402,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 +915,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);
@@ -1291,12 +1331,12 @@ static void cleanSubMesh( SMESH_subMesh * subMesh )
     if (SMESHDS_SubMesh * subMeshDS = subMesh->GetSubMeshDS())
     {
       SMESHDS_Mesh * meshDS = subMesh->GetFather()->GetMeshDS();
-      int nbElems = subMeshDS->NbElements();
+      smIdType nbElems = subMeshDS->NbElements();
       if ( nbElems > 0 )
         for ( SMDS_ElemIteratorPtr ite = subMeshDS->GetElements(); ite->more(); )
           meshDS->RemoveFreeElement( ite->next(), subMeshDS );
 
-      int nbNodes = subMeshDS->NbNodes();
+      smIdType nbNodes = subMeshDS->NbNodes();
       if ( nbNodes > 0 )
         for ( SMDS_NodeIteratorPtr itn = subMeshDS->GetNodes(); itn->more() ; )
         {
@@ -1405,6 +1445,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event)
       loadDependentMeshes();
       ComputeSubMeshStateEngine( SUBMESH_LOADED );
       //break;
+      // fall through
     case CHECK_COMPUTE_STATE:
       if ( IsMeshComputed() )
         _computeState = COMPUTE_OK;
@@ -1456,6 +1497,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event)
         }
         break;
       }
+      // fall through
     case COMPUTE:
     case COMPUTE_SUBMESH:
       {
@@ -1475,11 +1517,14 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event)
         if (_father->HasShapeToMesh() ) {
           bool subComputed = false, subFailed = false;
           if (!algo->OnlyUnaryInput()) {
-            if ( event == COMPUTE /*&&
-                 ( algo->NeedDiscreteBoundary() || algo->SupportSubmeshes() )*/)
-              shape = getCollection( gen, algo, subComputed, subFailed, algo->SubMeshesToCompute());
-            else
-              subComputed = SubMeshesComputed( & subFailed );
+            //  --- commented for bos#22320 to compute all sub-shapes at once if possible;
+            //  --- in case COMPUTE_SUBMESH, set of sub-shapes is limited
+            //  --- by calling SetAllowedSubShapes()
+            // if ( event == COMPUTE )
+            //   shape = getCollection( gen, algo, subComputed, subFailed, algo->SubMeshesToComput;
+            // else
+            //   subComputed = SubMeshesComputed( & subFailed );
+            shape = getCollection( gen, algo, subComputed, subFailed, algo->SubMeshesToCompute());
           }
           else {
             subComputed = SubMeshesComputed();
@@ -1607,8 +1652,9 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event)
             ((SMESHDS_Hypothesis*)hyps.front())->SaveTo( hypStr.Stream() );
             hypStr << " ";
           }
-          cout << _algo->GetName()
-               << " " << _father->GetSubMesh( subS.Current() )->GetId()
+          cout << _father->GetSubMesh( subS.Current() )->GetId()
+               << " " << ( ret ? "OK" : "FAIL" )
+               << " " << _algo->GetName()
                << " " << hypStr << endl;
         }
 #endif
@@ -1683,6 +1729,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
@@ -1717,6 +1765,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event)
       loadDependentMeshes();
       ComputeSubMeshStateEngine( SUBMESH_LOADED );
       //break;
+      // fall through
     case CHECK_COMPUTE_STATE:
       if ( IsMeshComputed() )
         _computeState = COMPUTE_OK;
@@ -1742,6 +1791,8 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event)
       break;
     case COMPUTE:               // nothing to do
       break;
+    case COMPUTE_SUBMESH:       // nothing to do
+      break;
     case COMPUTE_CANCELED:      // nothing to do
       break;
     case CLEAN:
@@ -1866,7 +1917,7 @@ bool SMESH_subMesh::Evaluate(MapShapeNbElems& aResMap)
   bool ret = true;
 
   if (_subShape.ShapeType() == TopAbs_VERTEX) {
-    vector<int> aVec(SMDSEntity_Last,0);
+    vector<smIdType> aVec(SMDSEntity_Last,0);
     aVec[SMDSEntity_Node] = 1;
     aResMap.insert(make_pair(this,aVec));
     return ret;
@@ -1893,7 +1944,7 @@ bool SMESH_subMesh::Evaluate(MapShapeNbElems& aResMap)
         SMESH_subMesh* sm = smIt->next();
         int dim = SMESH_Gen::GetShapeDim( sm->GetSubShape() );
         if (dim < dimToCheck) break; // the rest subMeshes are all of less dimension
-        const vector<int> & nbs = aResMap[ sm ];
+        const vector<smIdType> & nbs = aResMap[ sm ];
         subMeshEvaluated = (std::accumulate( nbs.begin(), nbs.end(), 0 ) > 0 );
       }
       if ( !subMeshEvaluated )
@@ -1903,7 +1954,7 @@ bool SMESH_subMesh::Evaluate(MapShapeNbElems& aResMap)
 
     if ( IsMeshComputed() )
     {
-      vector<int> & nbEntities = aResMap[ this ];
+      vector<smIdType> & nbEntities = aResMap[ this ];
       nbEntities.resize( SMDSEntity_Last, 0 );
       if ( SMESHDS_SubMesh* sm = GetSubMeshDS() )
       {
@@ -1917,7 +1968,7 @@ bool SMESH_subMesh::Evaluate(MapShapeNbElems& aResMap)
     {
       ret = algo->Evaluate((*_father), _subShape, aResMap);
     }
-    aResMap.insert( make_pair( this,vector<int>(0)));
+    aResMap.insert( make_pair( this,vector<smIdType>(0)));
   }
 
   return ret;
@@ -2101,7 +2152,7 @@ void SMESH_subMesh::removeSubMeshElementsAndNodes()
 //           meshed at once along with _subShape
 //=======================================================================
 
-TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * theGen,
+TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * /*theGen*/,
                                           SMESH_Algo* theAlgo,
                                           bool &      theSubComputed,
                                           bool &      theSubFailed,
@@ -2115,8 +2166,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
@@ -2134,6 +2186,8 @@ TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * theGen,
     const TopoDS_Shape&  S = subMesh->_subShape;
     if ( S.ShapeType() != this->_subShape.ShapeType() )
       continue;
+    if ( _allowedSubShapes && !_allowedSubShapes->IsEmpty() && !_allowedSubShapes->Contains( S ))
+      continue;
     if ( subMesh == this )
     {
       aBuilder.Add( aCompound, S );
@@ -2143,7 +2197,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() )
@@ -2153,7 +2209,7 @@ TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * theGen,
     }
   }
 
-  return aCompound;
+  return theSubs.size() == 1 ? theSubs[0]->GetSubShape() : aCompound;
 }
 
 //=======================================================================
@@ -2276,9 +2332,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
   {
@@ -2286,6 +2342,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() )
@@ -2449,7 +2506,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();
@@ -2548,9 +2606,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
  */
 //================================================================================
 
@@ -2591,8 +2649,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() ))