Salome HOME
Merge from V5_1_main branch 24/11/2010
[modules/smesh.git] / src / SMESH / SMESH_subMesh.cxx
index d93b598a50336f83786885dd011ef5ac68206e7b..69b33a94c85ad2861a6576b10c4a08d373140705 100644 (file)
@@ -1,4 +1,4 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+//  Copyright (C) 2007-2010  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
@@ -19,6 +19,7 @@
 //
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : SMESH_subMesh.cxx
 //  Author : Paul RASCLE, EDF
@@ -39,6 +40,7 @@
 
 #include "utilities.h"
 #include "OpUtil.hxx"
+#include "Basics_Utils.hxx"
 
 #include <BRep_Builder.hxx>
 #include <BRep_Tool.hxx>
@@ -263,7 +265,7 @@ bool SMESH_subMesh::SubMeshesComputed()
       break; // the rest subMeshes are all of less dimension
     SMESHDS_SubMesh * ds = sm->GetSubMeshDS();
     bool computeOk = (sm->GetComputeState() == COMPUTE_OK ||
-                      (ds && ( ds->NbNodes() || ds->NbElements() )));
+                      (ds && ( dimToCheck ? ds->NbElements() : ds->NbNodes()  )));
     if (!computeOk)
     {
       int type = ss.ShapeType();
@@ -370,23 +372,24 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn()
   case TopAbs_COMPOUND:
     {
       //MESSAGE("compound");
-      for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More();
-           exp.Next())
+      for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More();exp.Next())
       {
         InsertDependence(exp.Current());
       }
-      for (TopExp_Explorer exp(_subShape, TopAbs_SHELL, TopAbs_SOLID); exp.More();
-           exp.Next())
+      for (TopExp_Explorer exp(_subShape, TopAbs_SHELL, TopAbs_SOLID); exp.More(); exp.Next())
       {
+        if ( BRep_Tool::IsClosed(exp.Current() ))
           InsertDependence(exp.Current());      //only shell not in solid
+        else
+          for (TopExp_Explorer expF(exp.Current(), TopAbs_FACE); expF.More();expF.Next())
+            InsertDependence(expF.Current());    // issue 0020959: HEXA_3D fails on shell
+
       }
-      for (TopExp_Explorer exp(_subShape, TopAbs_FACE, TopAbs_SHELL); exp.More();
-           exp.Next())
+      for (TopExp_Explorer exp(_subShape, TopAbs_FACE, TopAbs_SHELL); exp.More();exp.Next())
       {
         InsertDependence(exp.Current());
       }
-      for (TopExp_Explorer exp(_subShape, TopAbs_EDGE, TopAbs_FACE); exp.More();
-           exp.Next())
+      for (TopExp_Explorer exp(_subShape, TopAbs_EDGE, TopAbs_FACE); exp.More();exp.Next())
       {
         InsertDependence(exp.Current());
       }
@@ -394,9 +397,8 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn()
     }
   case TopAbs_COMPSOLID:
     {
-                //MESSAGE("compsolid");
-      for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More();
-           exp.Next())
+      //MESSAGE("compsolid");
+      for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More(); exp.Next())
       {
         InsertDependence(exp.Current());
       }
@@ -405,8 +407,7 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn()
   case TopAbs_SHELL:
     {
       //MESSAGE("shell");
-      for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More();
-           exp.Next())
+      for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More(); exp.Next())
       {
         InsertDependence(exp.Current());
       }
@@ -415,8 +416,7 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn()
   case TopAbs_WIRE:
     {
       //MESSAGE("wire");
-      for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More();
-           exp.Next())
+      for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More(); exp.Next())
       {
         InsertDependence(exp.Current());
       }
@@ -426,8 +426,7 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn()
     {
       //MESSAGE("solid");
       if(_father->HasShapeToMesh()) {
-        for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More();
-             exp.Next())
+        for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More();exp.Next())
         {
           InsertDependence(exp.Current());
         }
@@ -437,8 +436,7 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn()
   case TopAbs_FACE:
     {
       //MESSAGE("face");
-      for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More();
-           exp.Next())
+      for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More();exp.Next())
       {
         InsertDependence(exp.Current());
       }
@@ -447,11 +445,10 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn()
   case TopAbs_EDGE:
     {
       //MESSAGE("edge");
-      for (TopExp_Explorer exp(_subShape, TopAbs_VERTEX); exp.More();
-           exp.Next())
+      for (TopExp_Explorer exp(_subShape, TopAbs_VERTEX); exp.More(); exp.Next())
       {
-                        InsertDependence(exp.Current());
-                      }
+        InsertDependence(exp.Current());
+      }
       break;
     }
   case TopAbs_VERTEX:
@@ -1003,9 +1000,12 @@ SMESH_Hypothesis::Hypothesis_Status
     if ( ret == SMESH_Hypothesis::HYP_OK &&
          !algo->NeedDescretBoundary()    &&
          !algo->SupportSubmeshes()) {
+      TopoDS_Shape algoAssignedTo, otherAssignedTo;
+      gen->GetAlgo( *_father, _subShape, &algoAssignedTo );
       map<int, SMESH_subMesh*>::reverse_iterator i_sm = _mapDepend.rbegin();
       for ( ; ( ret == SMESH_Hypothesis::HYP_OK && i_sm != _mapDepend.rend()) ; ++i_sm )
-        if ( gen->GetAlgo( *_father, i_sm->second->_subShape ))
+        if ( gen->GetAlgo( *_father, i_sm->second->_subShape, &otherAssignedTo ) &&
+             SMESH_MesherHelper::IsSubShape( /*sub=*/otherAssignedTo, /*main=*/algoAssignedTo ))
           ret = SMESH_Hypothesis::HYP_HIDING_ALGO;
     }
   }
@@ -1370,6 +1370,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
           algo->InitComputeError();
           MemoryReserve aMemoryReserve;
           SMDS_Mesh::CheckMemory();
+          Kernel_Utils::Localizer loc;
           if ( !_father->HasShapeToMesh() ) // no shape
           {
             SMESH_MesherHelper helper( *_father );
@@ -1427,18 +1428,29 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
           else
             ret = false;
         }
-        if (ret && !_alwaysComputed && shape == _subShape) { // check if anything was built
-          ret = ( GetSubMeshDS() && ( GetSubMeshDS()->NbElements() || GetSubMeshDS()->NbNodes() ));
+        TopExp_Explorer subS(shape, _subShape.ShapeType());
+        if (ret) // check if anything was built
+        {
+          for (; ret && subS.More(); subS.Next())
+            ret = _father->GetSubMesh( subS.Current() )->IsMeshComputed();
         }
         bool isComputeErrorSet = !CheckComputeError( algo, shape );
         if (!ret && !isComputeErrorSet)
         {
           // Set _computeError
-          if ( !_computeError )
-            _computeError = SMESH_ComputeError::New();
-          if ( _computeError->IsOK() )
-            _computeError->myName = COMPERR_ALGO_FAILED;
-          _computeState = FAILED_TO_COMPUTE;
+          for (subS.ReInit(); subS.More(); subS.Next())
+          {
+            SMESH_subMesh* sm = _father->GetSubMesh( subS.Current() );
+            if ( !sm->IsMeshComputed() )
+            {
+              if ( !sm->_computeError )
+                sm->_computeError = SMESH_ComputeError::New();
+              if ( sm->_computeError->IsOK() )
+                sm->_computeError->myName = COMPERR_ALGO_FAILED;
+              sm->_computeState = FAILED_TO_COMPUTE;
+              sm->_computeError->myAlgo = algo;
+            }
+          }
         }
         if (ret)
         {
@@ -1535,6 +1547,8 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
     switch (event)
     {
     case MODIF_ALGO_STATE:
+      if ( !IsEmpty() )
+        ComputeStateEngine( CLEAN );
       algo = gen->GetAlgo((*_father), _subShape);
       if (algo && !algo->NeedDescretBoundary())
         CleanDependsOn(); // clean sub-meshes with event CLEAN