Salome HOME
Merge multi-study removal branch.
[modules/smesh.git] / src / SMESH / SMESH_Algo.cxx
index b7992de2f74473d3528e79b097a440dd69a918e6..c4fbb42cfe3a73b423ebda23500bf2a467e04058 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016  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
@@ -175,8 +175,8 @@ const SMESH_Algo::Features& SMESH_Algo::GetFeatures( const std::string& algoType
  */
 //=============================================================================
 
-SMESH_Algo::SMESH_Algo (int hypId, int studyId, SMESH_Gen * gen)
-  : SMESH_Hypothesis(hypId, studyId, gen)
+SMESH_Algo::SMESH_Algo (int hypId, SMESH_Gen * gen)
+  : SMESH_Hypothesis(hypId, gen)
 {
   _compatibleAllHypFilter = _compatibleNoAuxHypFilter = NULL;
   _onlyUnaryInput = _requireDiscreteBoundary = _requireShape = true;
@@ -204,26 +204,26 @@ SMESH_Algo::~SMESH_Algo()
  */
 //=============================================================================
 
-SMESH_0D_Algo::SMESH_0D_Algo(int hypId, int studyId, SMESH_Gen* gen)
-  : SMESH_Algo(hypId, studyId, gen)
+SMESH_0D_Algo::SMESH_0D_Algo(int hypId, SMESH_Gen* gen)
+  : SMESH_Algo(hypId, gen)
 {
   _shapeType = (1 << TopAbs_VERTEX);
   _type = ALGO_0D;
 }
-SMESH_1D_Algo::SMESH_1D_Algo(int hypId, int studyId, SMESH_Gen* gen)
-  : SMESH_Algo(hypId, studyId, gen)
+SMESH_1D_Algo::SMESH_1D_Algo(int hypId, SMESH_Gen* gen)
+  : SMESH_Algo(hypId, gen)
 {
   _shapeType = (1 << TopAbs_EDGE);
   _type = ALGO_1D;
 }
-SMESH_2D_Algo::SMESH_2D_Algo(int hypId, int studyId, SMESH_Gen* gen)
-  : SMESH_Algo(hypId, studyId, gen)
+SMESH_2D_Algo::SMESH_2D_Algo(int hypId, SMESH_Gen* gen)
+  : SMESH_Algo(hypId, gen)
 {
   _shapeType = (1 << TopAbs_FACE);
   _type = ALGO_2D;
 }
-SMESH_3D_Algo::SMESH_3D_Algo(int hypId, int studyId, SMESH_Gen* gen)
-  : SMESH_Algo(hypId, studyId, gen)
+SMESH_3D_Algo::SMESH_3D_Algo(int hypId, SMESH_Gen* gen)
+  : SMESH_Algo(hypId, gen)
 {
   _shapeType = (1 << TopAbs_SOLID);
   _type = ALGO_3D;
@@ -231,7 +231,7 @@ SMESH_3D_Algo::SMESH_3D_Algo(int hypId, int studyId, SMESH_Gen* gen)
 
 //=============================================================================
 /*!
- * Usually an algoritm has nothing to save
+ * Usually an algorithm has nothing to save
  */
 //=============================================================================
 
@@ -412,7 +412,7 @@ bool SMESH_Algo::GetSortedNodesOnEdge(const SMESHDS_Mesh*                   theM
     return false;
 
   SMESHDS_SubMesh * eSubMesh = theMesh->MeshElements( theEdge );
-  if ( !eSubMesh || ( eSubMesh->NbElements()==0 &&  eSubMesh->NbNodes() == 0))
+  if ( !eSubMesh || ( eSubMesh->NbElements() == 0 && eSubMesh->NbNodes() == 0))
     return false; // edge is not meshed
 
   int nbNodes = 0;
@@ -440,16 +440,18 @@ bool SMESH_Algo::GetSortedNodesOnEdge(const SMESHDS_Mesh*                   theM
   TopExp::Vertices(theEdge, v1, v2);
   const SMDS_MeshNode* n1 = VertexNode( v1, eSubMesh, 0 );
   const SMDS_MeshNode* n2 = VertexNode( v2, eSubMesh, 0 );
+  const SMDS_MeshNode* nEnd[2] = { nbNodes ? theNodes.begin()->second  : 0,
+                                   nbNodes ? theNodes.rbegin()->second : 0 };
   Standard_Real f, l;
   BRep_Tool::Range(theEdge, f, l);
   if ( v1.Orientation() != TopAbs_FORWARD )
     std::swap( f, l );
-  if ( n1 && ++nbNodes )
+  if ( n1 && n1 != nEnd[0] && n1 != nEnd[1] && ++nbNodes )
     theNodes.insert( make_pair( f, n1 ));
-  if ( n2 && ++nbNodes )
+  if ( n2 && n2 != nEnd[0] && n2 != nEnd[1] && ++nbNodes )
     theNodes.insert( make_pair( l, n2 ));
 
-  return theNodes.size() == nbNodes;
+  return (int)theNodes.size() == nbNodes;
 }
 
 //================================================================================
@@ -469,7 +471,7 @@ SMESH_Algo::GetCompatibleHypoFilter(const bool ignoreAuxiliary) const
     {
       SMESH_HypoFilter* filter = new SMESH_HypoFilter();
       filter->Init( filter->HasName( _compatibleHypothesis[0] ));
-      for ( int i = 1; i < _compatibleHypothesis.size(); ++i )
+      for ( size_t i = 1; i < _compatibleHypothesis.size(); ++i )
         filter->Or( filter->HasName( _compatibleHypothesis[ i ] ));
 
       SMESH_HypoFilter* filterNoAux = new SMESH_HypoFilter( filter );
@@ -494,10 +496,11 @@ SMESH_Algo::GetCompatibleHypoFilter(const bool ignoreAuxiliary) const
  */
 //================================================================================
 
-GeomAbs_Shape SMESH_Algo::Continuity(TopoDS_Edge E1,
-                                     TopoDS_Edge E2)
+GeomAbs_Shape SMESH_Algo::Continuity(const TopoDS_Edge& theE1,
+                                     const TopoDS_Edge& theE2)
 {
-  //E1.Orientation(TopAbs_FORWARD), E2.Orientation(TopAbs_FORWARD); // avoid pb with internal edges
+  // avoid pb with internal edges
+  TopoDS_Edge E1 = theE1, E2 = theE2;
   if (E1.Orientation() > TopAbs_REVERSED) // INTERNAL
     E1.Orientation( TopAbs_FORWARD );
   if (E2.Orientation() > TopAbs_REVERSED) // INTERNAL
@@ -550,28 +553,35 @@ bool SMESH_Algo::IsStraight( const TopoDS_Edge & E,
   case GeomAbs_Hyperbola:
   case GeomAbs_Parabola:
     return false;
-  // case GeomAbs_BezierCurve:
-  // case GeomAbs_BSplineCurve:
-  // case GeomAbs_OtherCurve:
+    // case GeomAbs_BezierCurve:
+    // case GeomAbs_BSplineCurve:
+    // case GeomAbs_OtherCurve:
   default:;
   }
-  const double   f = curve.FirstParameter();
-  const double   l = curve.LastParameter();
-  const gp_Pnt  pf = curve.Value( f );
-  const gp_Pnt  pl = curve.Value( l );
-  const gp_Vec v1( pf, pl );
-  const double v1Len = v1.Magnitude();
-  if ( v1Len < std::numeric_limits< double >::min() )
+
+  // evaluate how far from a straight line connecting the curve ends
+  // stand internal points of the curve
+  double  f = curve.FirstParameter();
+  double  l = curve.LastParameter();
+  gp_Pnt pf = curve.Value( f );
+  gp_Pnt pl = curve.Value( l );
+  gp_Vec lineVec( pf, pl );
+  double lineLen2 = lineVec.SquareMagnitude();
+  if ( lineLen2 < std::numeric_limits< double >::min() )
     return false; // E seems closed
-  const double tol = Min( 10 * curve.Tolerance(), v1Len * 1e-2 );
+
+  double edgeTol = 10 * curve.Tolerance();
+  double lenTol2 = lineLen2 * 1e-4; 
+  double tol2 = Min( edgeTol * edgeTol, lenTol2 );
+
   const double nbSamples = 7;
   for ( int i = 0; i < nbSamples; ++i )
   {
-    const double  r = ( i + 1 ) / nbSamples;
-    const gp_Pnt pi = curve.Value( f * r + l * ( 1 - r ));
-    const gp_Vec vi( pf, pi );
-    const double  h = 0.5 * v1.Crossed( vi ).Magnitude() / v1Len;
-    if ( h > tol )
+    double  r = ( i + 1 ) / nbSamples;
+    gp_Pnt pi = curve.Value( f * r + l * ( 1 - r ));
+    gp_Vec vi( pf, pi );
+    double h2 = lineVec.Crossed( vi ).SquareMagnitude() / lineLen2;
+    if ( h2 > tol2 )
       return false;
   }
   return true;
@@ -583,8 +593,10 @@ bool SMESH_Algo::IsStraight( const TopoDS_Edge & E,
  */
 //================================================================================
 
-bool SMESH_Algo::isDegenerated( const TopoDS_Edge & E )
+bool SMESH_Algo::isDegenerated( const TopoDS_Edge & E, const bool checkLength )
 {
+  if ( checkLength )
+    return EdgeLength( E ) == 0;
   double f,l;
   TopLoc_Location loc;
   Handle(Geom_Curve) C = BRep_Tool::Curve( E, loc, f,l );
@@ -746,7 +758,7 @@ SMESH_Algo::EMeshError SMESH_Algo::GetMeshError(SMESH_subMesh* subMesh)
     if ( !fIt->more() )
       return MEr_EMPTY;
 
-    // We check that olny links on EDGEs encouter once, the rest links, twice
+    // We check that only links on EDGEs encouter once, the rest links, twice
     set< SMESH_TLink > links;
     while ( fIt->more() )
     {
@@ -847,6 +859,16 @@ bool SMESH_Algo::Compute(SMESH_Mesh & /*aMesh*/, SMESH_MesherHelper* /*aHelper*/
   return error( COMPERR_BAD_INPUT_MESH, "Mesh built on shape expected");
 }
 
+//=======================================================================
+//function : IsApplicableToShape
+//purpose  : Return true if the algorithm can mesh a given shape
+//=======================================================================
+
+bool SMESH_Algo::IsApplicableToShape(const TopoDS_Shape & shape, bool toCheckAll) const
+{
+  return true;
+}
+
 //=======================================================================
 //function : CancelCompute
 //purpose  : Sets _computeCanceled to true. It's usage depends on