Salome HOME
PAL8196. Fix GetAlgo() for the case with the same algo on several ancestors
[modules/smesh.git] / src / SMESH / SMESH_Gen.cxx
index 44000dfac64f0a05e6128c064f375586c69e0151..7a3c34a50a0f8d309bcebfc26aacba9878ac1b16 100644 (file)
@@ -1,23 +1,23 @@
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //
 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
-// 
-//  This library is free software; you can redistribute it and/or 
-//  modify it under the terms of the GNU Lesser General Public 
-//  License as published by the Free Software Foundation; either 
-//  version 2.1 of the License. 
-// 
-//  This library is distributed in the hope that it will be useful, 
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
-//  Lesser General Public License for more details. 
-// 
-//  You should have received a copy of the GNU Lesser General Public 
-//  License along with this library; if not, write to the Free Software 
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
-// 
-//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
 //
 //
 //
 
 #include "SMESH_Gen.hxx"
 #include "SMESH_subMesh.hxx"
+#include "SMESH_HypoFilter.hxx"
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
 
 #include "utilities.h"
 #include "OpUtil.hxx"
+#include "Utils_ExceptHandlers.hxx"
 
 #include <gp_Pnt.hxx>
 #include <BRep_Tool.hxx>
 #include <TopTools_ListOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
-#include "Utils_ExceptHandlers.hxx"
 
+using namespace std;
 
 //=============================================================================
 /*!
@@ -56,7 +58,7 @@ SMESH_Gen::SMESH_Gen()
 
 //=============================================================================
 /*!
- * 
+ *
  */
 //=============================================================================
 
@@ -67,7 +69,7 @@ SMESH_Gen::~SMESH_Gen()
 
 //=============================================================================
 /*!
- * 
+ *
  */
 //=============================================================================
 
@@ -96,7 +98,7 @@ SMESH_Gen::~SMESH_Gen()
 
 //=============================================================================
 /*!
- * 
+ *
  */
 //=============================================================================
 
@@ -115,7 +117,7 @@ throw(SALOME_Exception)
 
        StudyContextStruct *myStudyContext = GetStudyContext(studyId);
 
-       // create a new SMESH_mesh object 
+       // create a new SMESH_mesh object
 
        SMESH_Mesh *mesh = new SMESH_Mesh(_localId++,
                studyId,
@@ -131,7 +133,7 @@ throw(SALOME_Exception)
 
 //=============================================================================
 /*!
- * 
+ *
  */
 //=============================================================================
 
@@ -139,7 +141,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
 {
   MESSAGE("SMESH_Gen::Compute");
   //   bool isDone = false;
-  /* 
+  /*
      Algo : s'appuie ou non sur une geometrie
      Si geometrie:
      Vertex : rien à faire (range le point)
@@ -157,19 +159,22 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
 
   bool ret = true;
 
-  if ( !CheckAlgoState( aMesh, aShape ))
-  {
-    INFOS( "ABORT MESHING: some algos or hypothesis are missing");
-    return false;
-  }
+//   if ( !CheckAlgoState( aMesh, aShape ))
+//   {
+//     INFOS( "ABORT MESHING: some algos or hypothesis are missing");
+//     return false;
+//   }
 
   SMESH_subMesh *sm = aMesh.GetSubMesh(aShape);
 
+  if ( sm->GetComputeState() == SMESH_subMesh::COMPUTE_OK )
+    return true; // already computed
+
   // -----------------------------------------------------------------
   // apply algos that do not require descretized boundaries, starting
   // from the most complex shapes
   // -----------------------------------------------------------------
-  
+
   // map containing all subshapes in the order: vertices, edges, faces...
   const map<int, SMESH_subMesh*>& smMap = sm->DependsOn();
   map<int, SMESH_subMesh*>::const_reverse_iterator revItSub = smMap.rbegin();
@@ -181,11 +186,14 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
     if ( GetShapeDim( aSubShape ) < 1 ) break;
 
     SMESH_Algo* algo = GetAlgo( aMesh, aSubShape );
-    if (algo &&
-        !algo->NeedDescretBoundary() &&
-        smToCompute->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE )
-    {
-      ret = smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
+    if (algo && !algo->NeedDescretBoundary()) {
+      if (smToCompute->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE) {
+        ret = smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
+      } else if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE) {
+        // JFA for PAL6524
+        ret = false;
+      } else {
+      }
     }
     if (!ret)
       return false;
@@ -199,50 +207,51 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
     else
       smToCompute = 0;
   }
-    
+
   // -----------------------------------------------
   // mesh the rest subshapes starting from vertices
   // -----------------------------------------------
-  
-  smToCompute = sm->GetFirstToCompute();
-  while (smToCompute)
+
+  int i, nbSub = smMap.size();
+  map<int, SMESH_subMesh*>::const_iterator itSub = smMap.begin();
+  for ( i = 0; i <= nbSub; ++i ) // loop on the whole map plus <sm>
   {
+    if ( itSub == smMap.end() )
+      smToCompute = sm;
+    else
+      smToCompute = (itSub++)->second;
+    if (smToCompute->GetComputeState() != SMESH_subMesh::READY_TO_COMPUTE) {
+      if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE)
+        ret = false;
+      continue;
+    }
     TopoDS_Shape subShape = smToCompute->GetSubShape();
-    int dim = GetShapeDim(subShape);
-    if (dim > 0)
+    if ( subShape.ShapeType() != TopAbs_VERTEX )
     {
-      //MESSAGE ( "MESH shape id=" << smToCompute->GetId() <<
-        //       " type=" << smToCompute->GetSubShape().ShapeType());
-      bool ret1 = smToCompute->ComputeStateEngine(SMESH_subMesh::COMPUTE);
-      ret = ret && ret1;
+      if ( !smToCompute->ComputeStateEngine(SMESH_subMesh::COMPUTE) )
+        ret = false;
     }
     else
     {
-      ASSERT(dim == 0);
-      ASSERT(smToCompute->_vertexSet == false);
       TopoDS_Vertex V1 = TopoDS::Vertex(subShape);
       gp_Pnt P1 = BRep_Tool::Pnt(V1);
       SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
-      //MESSAGE("point "<<nodeId<<" "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z());
       SMDS_MeshNode * node = meshDS->AddNode(P1.X(), P1.Y(), P1.Z());
       if ( node ) {  // san - increase robustness
         meshDS->SetNodeOnVertex(node, V1);
-        smToCompute->GetSubMeshDS();
-        smToCompute->_vertexSet = true;
         smToCompute->ComputeStateEngine(SMESH_subMesh::COMPUTE);
       }
     }
-    smToCompute = sm->GetFirstToCompute();
   }
 
-  MESSAGE( "VSR - SMESH_Gen::Compute() finished);
+  MESSAGE( "VSR - SMESH_Gen::Compute() finished, OK = " << ret);
   return ret;
 }
 
 
 //=======================================================================
 //function : checkConformIgnoredAlgos
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 static bool checkConformIgnoredAlgos(SMESH_Mesh&               aMesh,
@@ -270,7 +279,7 @@ static bool checkConformIgnoredAlgos(SMESH_Mesh&               aMesh,
 
     const SMESH_Algo* algo = dynamic_cast<const SMESH_Algo*> (aHyp);
     ASSERT ( algo );
-    
+
     if ( aLocIgnoAlgo ) // algo is hidden by a local algo of upper dim
     {
       INFOS( "Local <" << algo->GetName() << "> is hidden by local <"
@@ -285,7 +294,7 @@ static bool checkConformIgnoredAlgos(SMESH_Mesh&               aMesh,
       if ( dim < aMaxGlobIgnoDim )
       {
         // algo is hidden by a global algo
-        INFOS( ( isGlobal ? "Global" : "Local" ) 
+        INFOS( ( isGlobal ? "Global" : "Local" )
               << " <" << algo->GetName() << "> is hidden by global <"
               << aGlobIgnoAlgo->GetName() << ">");
       }
@@ -319,7 +328,7 @@ static bool checkConformIgnoredAlgos(SMESH_Mesh&               aMesh,
       }
     }
   }
-  
+
   return ret;
 }
 
@@ -339,7 +348,7 @@ static bool checkMissing(SMESH_Gen*                aGen,
 {
   if ( aSubMesh->GetSubShape().ShapeType() == TopAbs_VERTEX)
     return true;
-  
+
   //MESSAGE("=====checkMissing");
 
   int ret = true;
@@ -364,12 +373,12 @@ static bool checkMissing(SMESH_Gen*                aGen,
     // notify if an algo missing hyp is attached to aSubMesh
     algo = aGen->GetAlgo( aMesh, aSubMesh->GetSubShape() );
     ASSERT( algo );
-    bool isGlobalAlgo = aGen->IsGlobalAlgo( algo, aMesh );
-    if (!isGlobalAlgo || !globalChecked[ algo->GetDim() ])
+    bool IsGlobalHypothesis = aGen->IsGlobalHypothesis( algo, aMesh );
+    if (!IsGlobalHypothesis || !globalChecked[ algo->GetDim() ])
     {
-      INFOS( "ERROR: " << (isGlobalAlgo ? "Global " : "Local ")
+      INFOS( "ERROR: " << (IsGlobalHypothesis ? "Global " : "Local ")
             << "<" << algo->GetName() << "> misses some hypothesis");
-      if (isGlobalAlgo)
+      if (IsGlobalHypothesis)
         globalChecked[ algo->GetDim() ] = true;
     }
     ret = false;
@@ -386,7 +395,7 @@ static bool checkMissing(SMESH_Gen*                aGen,
   // re-start checking NO_ALGO state
   ASSERT (algo);
   bool isTopLocalAlgo =
-    ( aTopAlgoDim <= algo->GetDim() && !aGen->IsGlobalAlgo( algo, aMesh ));
+    ( aTopAlgoDim <= algo->GetDim() && !aGen->IsGlobalHypothesis( algo, aMesh ));
   if (!algo->NeedDescretBoundary() || isTopLocalAlgo)
   {
     bool checkNoAlgo2 = ( algo->NeedDescretBoundary() );
@@ -433,11 +442,11 @@ bool SMESH_Gen::CheckAlgoState(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape)
   SMESH_subMesh* sm = aMesh.GetSubMesh(aShape);
   const SMESHDS_Mesh* meshDS = aMesh.GetMeshDS();
   TopoDS_Shape mainShape = meshDS->ShapeToMesh();
-  
+
   // -----------------
   // get global algos
   // -----------------
-  
+
   const SMESH_Algo* aGlobAlgoArr[] = {0,0,0,0};
 
   const list<const SMESHDS_Hypothesis*>& listHyp = meshDS->GetHypothesis( mainShape );
@@ -450,13 +459,13 @@ bool SMESH_Gen::CheckAlgoState(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape)
 
     const SMESH_Algo* algo = dynamic_cast<const SMESH_Algo*> (aHyp);
     ASSERT ( algo );
-    
+
     int dim = algo->GetDim();
     aGlobAlgoArr[ dim ] = algo;
 
     hasAlgo = true;
   }
-  
+
   // --------------------------------------------------------
   // info on algos that will be ignored because of ones that
   // don't NeedDescretBoundary() attached to super-shapes,
@@ -518,7 +527,7 @@ bool SMESH_Gen::CheckAlgoState(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape)
   // ----------------------------------------------------------------
 
   //MESSAGE( "---info on missing hypothesis and find out if all needed algos are");
-  
+
   // find max dim of global algo
   int aTopAlgoDim = 0;
   for (dim = 3; dim > 0; dim--)
@@ -568,60 +577,19 @@ bool SMESH_Gen::CheckAlgoState(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape)
 }
 
 //=======================================================================
-//function : IsGlobalAlgo
+//function : IsGlobalHypothesis
 //purpose  : check if theAlgo is attached to the main shape
 //=======================================================================
 
-bool SMESH_Gen::IsGlobalAlgo(const SMESH_Algo* theAlgo, SMESH_Mesh& aMesh)
+bool SMESH_Gen::IsGlobalHypothesis(const SMESH_Hypothesis* theHyp, SMESH_Mesh& aMesh)
 {
-  const SMESHDS_Mesh* meshDS = aMesh.GetMeshDS();
-  TopoDS_Shape mainShape = meshDS->ShapeToMesh();
-  const list<const SMESHDS_Hypothesis*>& listHyp = meshDS->GetHypothesis( mainShape );
-  list<const SMESHDS_Hypothesis*>::const_iterator it=listHyp.begin();
-  for ( ; it != listHyp.end(); it++)
-    if ( *it == theAlgo )
-      return true;
-
-  return false;
-}
-
-
-//=======================================================================
-//function : getAlgoId
-//purpose  : return algo ID or -1 if not found
-//=======================================================================
-
-static int getAlgo(const list<const SMESHDS_Hypothesis*>& theHypList,
-                   const int                              theAlgoDim,
-                   const int                              theAlgoShapeType)
-{
-  list<const SMESHDS_Hypothesis*>::const_iterator it = theHypList.begin();
-  
-  int nb_algo = 0;
-  int algo_id = -1;
-  
-  while (it!=theHypList.end())
-  {
-    const SMESH_Hypothesis *anHyp = static_cast< const SMESH_Hypothesis *>( *it );
-    if (anHyp->GetType() > SMESHDS_Hypothesis::PARAM_ALGO &&
-        anHyp->GetDim() == theAlgoDim &&
-        ((anHyp->GetShapeType()) & (1 << theAlgoShapeType)))
-    {
-      nb_algo++;
-      algo_id = anHyp->GetID();
-      break;
-    }
-    
-    //if (nb_algo > 1) return -1;      // more than one algo
-    it++;
-  }
-
-  return algo_id;
+  SMESH_HypoFilter filter( SMESH_HypoFilter::Is( theHyp ));
+  return aMesh.GetHypothesis( aMesh.GetMeshDS()->ShapeToMesh(), filter, false );
 }
 
 //=============================================================================
 /*!
- * 
+ *
  */
 //=============================================================================
 
@@ -629,116 +597,29 @@ SMESH_Algo *SMESH_Gen::GetAlgo(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
 {
 //  MESSAGE("SMESH_Gen::GetAlgo");
 
-  const SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
-  int dim = GetShapeDim( aShape );
-  int shape_type = aShape.ShapeType();
-  int algo_id = -1;
+  SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() );
+  filter.And( filter.IsApplicableTo( aShape ));
 
-  algo_id = getAlgo( meshDS->GetHypothesis( aShape ), dim, shape_type );
+  list <const SMESHDS_Hypothesis * > algoList;
+  aMesh.GetHypotheses( aShape, filter, algoList, true );
 
-  if (algo_id < 0)
-  {
-    // try ansestors
-    TopTools_ListIteratorOfListOfShape ancIt( aMesh.GetAncestors( aShape ));
-    for (; ancIt.More(); ancIt.Next())
-    {
-      const TopoDS_Shape& ancestor = ancIt.Value();
-      algo_id = getAlgo( meshDS->GetHypothesis( ancestor ), dim, shape_type );
-      if ( algo_id >= 0 )
-        break;
-    }
-    if (algo_id < 0) return NULL;
+  if ( algoList.empty() )
+    return NULL;
+
+  if (algoList.size() > 1 ) { // check if there is one algo several times
+    list <const SMESHDS_Hypothesis * >::iterator algo = algoList.begin();
+    for ( ; algo != algoList.end(); ++algo )
+      if ( (*algo) != algoList.front() &&
+           (*algo)->GetName() != algoList.front()->GetName() )
+        return NULL;
   }
 
-  ASSERT(_mapAlgo.find(algo_id) != _mapAlgo.end());
-
-  return _mapAlgo[algo_id];
-  
-//     const SMESHDS_Hypothesis *theHyp = NULL;
-//     SMESH_Algo *algo = NULL;
-//     const SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
-//     int hypType;
-//     int hypId;
-//     int algoDim;
-
-//     // try shape first, then main shape
-
-//     TopoDS_Shape mainShape = meshDS->ShapeToMesh();
-//     const TopoDS_Shape *shapeToTry[2] = { &aShape, &mainShape };
-
-//     for (int iShape = 0; iShape < 2; iShape++)
-//     {
-//             TopoDS_Shape tryShape = (*shapeToTry[iShape]);
-
-//             const list<const SMESHDS_Hypothesis*>& listHyp =
-//                     meshDS->GetHypothesis(tryShape);
-//             list<const SMESHDS_Hypothesis*>::const_iterator it=listHyp.begin();
-               
-//             int nb_algo = 0;
-//             int shapeDim = GetShapeDim(aShape);
-//             int typeOfShape = aShape.ShapeType();
-
-//             while (it!=listHyp.end())
-//             {
-//                     const SMESHDS_Hypothesis *anHyp = *it;
-//                     hypType = anHyp->GetType();
-//                     //SCRUTE(hypType);
-//                     if (hypType > SMESHDS_Hypothesis::PARAM_ALGO)
-//                     {
-//                             switch (hypType)
-//                             {
-//                             case SMESHDS_Hypothesis::ALGO_1D:
-//                                     algoDim = 1;
-//                                     break;
-//                             case SMESHDS_Hypothesis::ALGO_2D:
-//                                     algoDim = 2;
-//                                     break;
-//                             case SMESHDS_Hypothesis::ALGO_3D:
-//                                     algoDim = 3;
-//                                     break;
-//                             default:
-//                                     algoDim = 0;
-//                                     break;
-//                             }
-//                             //SCRUTE(algoDim);
-//                             //SCRUTE(shapeDim);
-//                             //SCRUTE(typeOfShape);
-//                             if (shapeDim == algoDim)        // count only algos of shape dim.
-//                             {                               // discard algos for subshapes
-//                                     hypId = anHyp->GetID(); // (of lower dim.)
-//                                     ASSERT(_mapAlgo.find(hypId) != _mapAlgo.end());
-//                                     SMESH_Algo *anAlgo = _mapAlgo[hypId];
-//                                     //SCRUTE(anAlgo->GetShapeType());
-//                                     //if (anAlgo->GetShapeType() == typeOfShape)
-//                                     if ((anAlgo->GetShapeType()) & (1 << typeOfShape))
-//                                     {                       // only specific TopoDS_Shape
-//                                             nb_algo++;
-//                                             theHyp = anHyp;
-//                                     }
-//                             }
-//                     }
-//                     if (nb_algo > 1) return NULL;   // more than one algo
-//                     it++;
-//             }
-//             if (nb_algo == 1)               // one algo found : OK
-//                     break;                          // do not try a parent shape
-//     }
-
-//     if (!theHyp)
-//             return NULL;                    // no algo found
-
-//     hypType = theHyp->GetType();
-//     hypId = theHyp->GetID();
-
-//     ASSERT(_mapAlgo.find(hypId) != _mapAlgo.end());
-//     algo = _mapAlgo[hypId];
-//     //MESSAGE("Algo found " << algo->GetName() << " Id " << hypId);
-//     return algo;
+  return const_cast<SMESH_Algo*> ( static_cast<const SMESH_Algo* >( algoList.front() ));
 }
 
 //=============================================================================
 /*!
- * 
+ *
  */
 //=============================================================================
 
@@ -758,7 +639,7 @@ StudyContextStruct *SMESH_Gen::GetStudyContext(int studyId)
 
 //=============================================================================
 /*!
- * 
+ *
  */
 //=============================================================================
 
@@ -768,7 +649,7 @@ void SMESH_Gen::Save(int studyId, const char *aUrlOfFile)
 
 //=============================================================================
 /*!
- * 
+ *
  */
 //=============================================================================
 
@@ -778,7 +659,7 @@ void SMESH_Gen::Load(int studyId, const char *aUrlOfFile)
 
 //=============================================================================
 /*!
- * 
+ *
  */
 //=============================================================================
 
@@ -788,38 +669,7 @@ void SMESH_Gen::Close(int studyId)
 
 //=============================================================================
 /*!
- * 
- */
-//=============================================================================
-
-const char *SMESH_Gen::ComponentDataType()
-{
-}
-
-//=============================================================================
-/*!
- * 
- */
-//=============================================================================
-
-const char *SMESH_Gen::IORToLocalPersistentID(const char *IORString,
-       bool & IsAFile)
-{
-}
-
-//=============================================================================
-/*!
- * 
- */
-//=============================================================================
-
-const char *SMESH_Gen::LocalPersistentIDToIOR(const char *aLocalPersistentID)
-{
-}
-
-//=============================================================================
-/*!
- * 
+ *
  */
 //=============================================================================