Salome HOME
Update of CheckDone
[modules/smesh.git] / src / StdMeshers / StdMeshers_Adaptive1D.cxx
index 62a2cf5a9f1706e34b34896276f4df040b3fc068..fe539a1bd9367c10952f170f8203475e3dafc93c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2024  CEA, EDF, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 //
 #include "StdMeshers_Adaptive1D.hxx"
 
+#include "SMESHDS_Mesh.hxx"
 #include "SMESH_Gen.hxx"
+#include "SMESH_HypoFilter.hxx"
 #include "SMESH_Mesh.hxx"
 #include "SMESH_MesherHelper.hxx"
 #include "SMESH_Octree.hxx"
 #include "SMESH_subMesh.hxx"
-#include "SMESH_HypoFilter.hxx"
 
 #include <Utils_SALOME_Exception.hxx>
 
@@ -154,7 +155,7 @@ namespace // internal utils
   class AdaptiveAlgo : public StdMeshers_Regular_1D
   {
   public:
-    AdaptiveAlgo(int hypId, int studyId, SMESH_Gen* gen);
+    AdaptiveAlgo(int hypId, SMESH_Gen* gen);
     virtual bool Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape );
     virtual bool Evaluate(SMESH_Mesh &         theMesh,
                           const TopoDS_Shape & theShape,
@@ -240,15 +241,14 @@ namespace // internal utils
     BBox                         myBBox;
     BRepAdaptor_Surface          mySurface;
     ElementBndBoxTree*           myTree;
-    const Poly_Array1OfTriangle* myPolyTrias;
-    const TColgp_Array1OfPnt*    myNodes;
-    bool                         myOwnNodes;
+    TColgp_Array1OfPnt           myNodes;
 
     typedef vector<int> IntVec;
     IntVec                       myFoundTriaIDs;
 
     TriaTreeData( const TopoDS_Face& face, ElementBndBoxTree* triaTree );
-    ~TriaTreeData() { if ( myOwnNodes ) delete myNodes; myNodes = NULL; }
+    ~TriaTreeData() {
+    }
     virtual const Bnd_B3d* GetBox(int elemID) const { return &myTrias[elemID].myBox; }
     void PrepareToTriaSearch();
     void SetSizeByTrias( SegSizeTree& sizeTree, double deflection ) const;
@@ -310,7 +310,7 @@ namespace // internal utils
 
   TriaTreeData::TriaTreeData( const TopoDS_Face& face, ElementBndBoxTree* triaTree )
     : myTriasDeflection(0), mySurface( face ),
-      myTree(NULL), myPolyTrias(NULL), myNodes(NULL), myOwnNodes(false)
+      myTree(NULL)
   {
     TopLoc_Location loc;
     Handle(Poly_Triangulation) tr = BRep_Tool::Triangulation( face, loc );
@@ -318,21 +318,19 @@ namespace // internal utils
     {
       myFaceTol         = SMESH_MesherHelper::MaxTolerance( face );
       myTree            = triaTree;
-      myNodes           = & tr->Nodes();
-      myPolyTrias       = & tr->Triangles();
+      myNodes           = TColgp_Array1OfPnt( 1, tr->NbNodes() );
+      for (int ii = 1; ii <= tr->NbNodes(); ++ii) {
+        myNodes(ii) = tr->Node(ii);
+      }
       myTriasDeflection = tr->Deflection();
       if ( !loc.IsIdentity() ) // transform nodes if necessary
       {
-        TColgp_Array1OfPnt* trsfNodes = new TColgp_Array1OfPnt( myNodes->Lower(), myNodes->Upper() );
-        trsfNodes->Assign( *myNodes );
-        myNodes    = trsfNodes;
-        myOwnNodes = true;
         const gp_Trsf& trsf = loc;
-        for ( int i = trsfNodes->Lower(); i <= trsfNodes->Upper(); ++i )
-          trsfNodes->ChangeValue(i).Transform( trsf );
+        for ( int i = myNodes.Lower(); i <= myNodes.Upper(); ++i )
+          myNodes(i).Transform( trsf );
       }
-      for ( int i = myNodes->Lower(); i <= myNodes->Upper(); ++i )
-        myBBox.Add( myNodes->Value(i).XYZ() );
+      for ( int i = myNodes.Lower(); i <= myNodes.Upper(); ++i )
+        myBBox.Add( myNodes.Value(i).XYZ() );
     }
   }
   //================================================================================
@@ -344,14 +342,16 @@ namespace // internal utils
   void TriaTreeData::PrepareToTriaSearch()
   {
     if ( !myTrias.empty() ) return; // already done
-    if ( !myPolyTrias ) return;
+
+    TopLoc_Location loc;
+    Handle(Poly_Triangulation) tr = BRep_Tool::Triangulation( mySurface.Face(), loc );
+
+    if ( tr.IsNull() || !tr->NbTriangles() ) return;
 
     // get all boundary links and nodes on VERTEXes
     map< NLink, Segment* > linkToSegMap;
     map< NLink, Segment* >::iterator l2s;
     set< int > vertexNodes;
-    TopLoc_Location loc;
-    Handle(Poly_Triangulation) tr = BRep_Tool::Triangulation( mySurface.Face(), loc );
     if ( !tr.IsNull() )
     {
       TopTools_IndexedMapOfShape edgeMap;
@@ -376,21 +376,21 @@ namespace // internal utils
       {
         const NLink& link = (*l2s).first;
         (*l2s).second = & mySegments[ iS ];
-        mySegments[ iS ].Init( myNodes->Value( link.N1() ),
-                               myNodes->Value( link.N2() ));
+        mySegments[ iS ].Init( myNodes( link.N1() ),
+                               myNodes( link.N2() ));
       }
     }
 
     // initialize myTrias
-    myTrias.resize( myPolyTrias->Length() );
+    myTrias.resize( tr->NbTriangles() );
     Standard_Integer n1,n2,n3;
-    for ( int i = 1; i <= myPolyTrias->Upper(); ++i )
+    for ( int i = 1; i <= tr->NbTriangles(); ++i )
     {
       Triangle & t = myTrias[ i-1 ];
-      myPolyTrias->Value( i ).Get( n1,n2,n3 );
-      t.Init( myNodes->Value( n1 ),
-              myNodes->Value( n2 ),
-              myNodes->Value( n3 ));
+      tr->Triangle( i ).Get( n1,n2,n3 );
+      t.Init( myNodes.Value( n1 ),
+              myNodes.Value( n2 ),
+              myNodes.Value( n3 ));
       int nbSeg = 0;
       if (( l2s = linkToSegMap.find( NLink( n1, n2 ))) != linkToSegMap.end())
         t.mySegments[ nbSeg++ ] = l2s->second;
@@ -442,17 +442,18 @@ namespace // internal utils
     double a[3];
     bool   isDone[3];
     double size = -1., maxLinkLen;
-    int    jLongest;
+    int    jLongest = 0;
 
-    //int nbLinks = 0;
-    for ( int i = 1; i <= myPolyTrias->Upper(); ++i )
+    TopLoc_Location loc;
+    Handle(Poly_Triangulation) tr = BRep_Tool::Triangulation( mySurface.Face(), loc );
+    for ( int i = 1; i <= tr->NbTriangles(); ++i )
     {
       // get corners of a triangle
-      myPolyTrias->Value( i ).Get( n[0],n[1],n[2] );
+      tr->Triangle( i ).Get( n[0],n[1],n[2] );
       n[3] = n[0];
-      p[0] = myNodes->Value( n[0] );
-      p[1] = myNodes->Value( n[1] );
-      p[2] = myNodes->Value( n[2] );
+      p[0] = myNodes.Value( n[0] );
+      p[1] = myNodes.Value( n[1] );
+      p[2] = myNodes.Value( n[2] );
       p[3] = p[0];
       // get length of links and find the longest one
       maxLinkLen = 0;
@@ -492,7 +493,7 @@ namespace // internal utils
       }
       //cout << "SetSizeByTrias, i="<< i << " " << sz * factor << endl;
     }
-    // cout << "SetSizeByTrias, nn tria="<< myPolyTrias->Upper()
+    // cout << "SetSizeByTrias, nn tria="<< tr->NbTriangles()
     //      << " nb links" << nbLinks << " isConstSize="<<isConstSize
     //      << " " << size * factor << endl;
   }
@@ -519,6 +520,9 @@ namespace // internal utils
     if ( myFoundTriaIDs.empty() )
       return minDist2;
 
+    TopLoc_Location loc;
+    Handle(Poly_Triangulation) tr = BRep_Tool::Triangulation( mySurface.Face(), loc );
+
     Standard_Integer n[ 3 ];
     for ( size_t i = 0; i < myFoundTriaIDs.size(); ++i )
     {
@@ -528,14 +532,14 @@ namespace // internal utils
       t.myIsChecked = true;
 
       double d, minD2 = minDist2;
-      myPolyTrias->Value( myFoundTriaIDs[i]+1 ).Get( n[0],n[1],n[2] );
+      tr->Triangle( myFoundTriaIDs[i]+1 ).Get( n[0],n[1],n[2] );
       if ( avoidPnt && t.myHasNodeOnVertex )
       {
         bool avoidTria = false;
         for ( int i = 0; i < 3; ++i )
         {
-          const gp_Pnt& pn = myNodes->Value(n[i]);
-          if ( avoidTria = ( pn.SquareDistance( *avoidPnt ) <= tol2 ))
+          const gp_Pnt& pn = myNodes.Value(n[i]);
+          if (( avoidTria = ( pn.SquareDistance( *avoidPnt ) <= tol2 )))
             break;
           if ( !projectedOnly )
             minD2 = Min( minD2, pn.SquareDistance( p ));
@@ -555,7 +559,7 @@ namespace // internal utils
       else
       {
         for ( int i = 0; i < 3; ++i )
-          minD2 = Min( minD2, p.SquareDistance( myNodes->Value(n[i]) ));
+          minD2 = Min( minD2, p.SquareDistance( myNodes.Value(n[i]) ));
         if ( minD2 < t.myMaxSize2  && ( t.DistToProjection( p, d ) || t.DistToSegment( p, d )))
           minD2 = Min( minD2, d*d );
         minDist2 = Min( minDist2, minD2 );
@@ -653,7 +657,7 @@ namespace // internal utils
 
   //================================================================================
   /*!
-   * \brief Consturct ElementBndBoxTree of Poly_Triangulation of a FACE
+   * \brief Construct ElementBndBoxTree of Poly_Triangulation of a FACE
    */
   //================================================================================
 
@@ -703,7 +707,7 @@ namespace // internal utils
   void ElementBndBoxTree::buildChildrenData()
   {
     ElemTreeData* data = GetElemData();
-    for ( int i = 0; i < _elementIDs.size(); ++i )
+    for ( size_t i = 0; i < _elementIDs.size(); ++i )
     {
       const Bnd_B3d* elemBox = data->GetBox( _elementIDs[i] );
       for (int j = 0; j < 8; j++)
@@ -718,7 +722,7 @@ namespace // internal utils
     {
       ElementBndBoxTree* child = static_cast<ElementBndBoxTree*>( myChildren[j] );
       child->_elementIDs = data->myWorkIDs[ j ];
-      if ( child->_elementIDs.size() <= theMaxNbElemsInLeaf )
+      if ((int) child->_elementIDs.size() <= theMaxNbElemsInLeaf )
         child->myIsLeaf = true;
       data->myWorkIDs[ j ].clear();
     }
@@ -741,7 +745,7 @@ namespace // internal utils
       if ( isLeaf() )
       {
         ElemTreeData* data = GetElemData();
-        for ( int i = 0; i < _elementIDs.size(); ++i )
+        for ( size_t i = 0; i < _elementIDs.size(); ++i )
           if ( !data->GetBox( _elementIDs[i] )->IsOut( center, radius ))
             foundElemIDs.push_back( _elementIDs[i] );
       }
@@ -915,9 +919,8 @@ namespace // internal utils
 //function : StdMeshers_Adaptive1D
 //purpose  : Constructor
 StdMeshers_Adaptive1D::StdMeshers_Adaptive1D(int         hypId,
-                                             int         studyId,
                                              SMESH_Gen * gen)
-  :SMESH_Hypothesis(hypId, studyId, gen)
+  :SMESH_Hypothesis(hypId, gen)
 {
   myMinSize       = 1e-10;
   myMaxSize       = 1e+10;
@@ -937,7 +940,6 @@ StdMeshers_Adaptive1D::~StdMeshers_Adaptive1D()
 //function : SetDeflection
 //purpose  : 
 void StdMeshers_Adaptive1D::SetDeflection(double value)
-  throw(SALOME_Exception)
 {
   if (value <= std::numeric_limits<double>::min() )
     throw SALOME_Exception("Deflection must be greater that zero");
@@ -951,7 +953,6 @@ void StdMeshers_Adaptive1D::SetDeflection(double value)
 //function : SetMinSize
 //purpose  : Sets minimal allowed segment length
 void StdMeshers_Adaptive1D::SetMinSize(double minSize)
-  throw(SALOME_Exception)
 {
   if (minSize <= std::numeric_limits<double>::min() )
     throw SALOME_Exception("Min size must be greater that zero");
@@ -966,7 +967,6 @@ void StdMeshers_Adaptive1D::SetMinSize(double minSize)
 //function : SetMaxSize
 //purpose  : Sets maximal allowed segment length
 void StdMeshers_Adaptive1D::SetMaxSize(double maxSize)
-  throw(SALOME_Exception)
 {
   if (maxSize <= std::numeric_limits<double>::min() )
     throw SALOME_Exception("Max size must be greater that zero");
@@ -992,7 +992,7 @@ ostream & StdMeshers_Adaptive1D::SaveTo(ostream & save)
 istream & StdMeshers_Adaptive1D::LoadFrom(istream & load)
 {
   int dummyParam;
-  bool isOK = (load >> myMinSize >> myMaxSize >> myDeflection >> dummyParam >> dummyParam);
+  bool isOK = static_cast<bool>(load >> myMinSize >> myMaxSize >> myDeflection >> dummyParam >> dummyParam);
   if (!isOK)
     load.clear(ios::badbit | load.rdstate());
   return load;
@@ -1075,7 +1075,7 @@ SMESH_Algo* StdMeshers_Adaptive1D::GetAlgo() const
   if ( !myAlgo )
   {
     AdaptiveAlgo* newAlgo = 
-      new AdaptiveAlgo( _gen->GetANewId(), _studyId, _gen );
+      new AdaptiveAlgo( _gen->GetANewId(), _gen );
     newAlgo->SetHypothesis( this );
 
     ((StdMeshers_Adaptive1D*) this)->myAlgo = newAlgo;
@@ -1090,9 +1090,8 @@ SMESH_Algo* StdMeshers_Adaptive1D::GetAlgo() const
 //================================================================================
 
 AdaptiveAlgo::AdaptiveAlgo(int        hypId,
-                           int        studyId,
                            SMESH_Gen* gen)
-  : StdMeshers_Regular_1D( hypId, studyId, gen ),
+  : StdMeshers_Regular_1D( hypId, gen ),
     myHyp(NULL)
 {
   _name = "AdaptiveAlgo_1D";
@@ -1179,6 +1178,7 @@ bool AdaptiveAlgo::Compute(SMESH_Mesh &         theMesh,
       eData.AddPoint( eData.myPoints.end(), eData.myC3d.LastParameter() );
     }
   }
+  if ( myEdges.empty() ) return true;
   if ( _computeCanceled ) return false;
 
   // Take into account size of already existing segments
@@ -1196,7 +1196,7 @@ bool AdaptiveAlgo::Compute(SMESH_Mesh &         theMesh,
   StdMeshers_Regular_1D::_value[ DEFLECTION_IND ] = myHyp->GetDeflection();
 
   list< double > params;
-  for ( int iE = 0; iE < myEdges.size(); ++iE )
+  for ( size_t iE = 0; iE < myEdges.size(); ++iE )
   {
     EdgeData& eData = myEdges[ iE ];
     //cout << "E " << theMesh.GetMeshDS()->ShapeToIndex( eData.Edge() ) << endl;
@@ -1242,7 +1242,7 @@ bool AdaptiveAlgo::Compute(SMESH_Mesh &         theMesh,
 
     triaSearcher->SetSizeByTrias( sizeTree, myHyp->GetDeflection() );
 
-    for ( int iE = 0; iE < myEdges.size(); ++iE )
+    for ( size_t iE = 0; iE < myEdges.size(); ++iE )
     {
       EdgeData& eData = myEdges[ iE ];
 
@@ -1289,6 +1289,7 @@ bool AdaptiveAlgo::Compute(SMESH_Mesh &         theMesh,
         //cout << "E " << theMesh.GetMeshDS()->ShapeToIndex( eData.Edge() ) << endl;
         sizeDecreased = false;
         const gp_Pnt* avoidPnt = & eData.First().myP;
+        EdgeData::TPntIter pItLast = --eData.myPoints.end(), pItFirst = eData.myPoints.begin();
         for ( pIt1 = eData.myPoints.begin(); pIt1 != eData.myPoints.end();  )
         {
           double distToFace =
@@ -1306,25 +1307,22 @@ bool AdaptiveAlgo::Compute(SMESH_Mesh &         theMesh,
               //      << "\t SetSize " << allowedSize << " at "
               //      << pIt1->myP.X() <<", "<< pIt1->myP.Y()<<", "<<pIt1->myP.Z() << endl;
               pIt2 = pIt1;
-              if ( --pIt2 != eData.myPoints.end() && pIt2->mySegSize > allowedSize )
+              if ( pIt1 != pItFirst && ( --pIt2 )->mySegSize > allowedSize )
                 sizeTree.SetSize( eData.myC3d.Value( 0.6*pIt2->myU + 0.4*pIt1->myU ), allowedSize );
               pIt2 = pIt1;
-              if ( ++pIt2 != eData.myPoints.end() && pIt2->mySegSize > allowedSize )
+              if ( pIt1 != pItLast  && ( ++pIt2 )->mySegSize > allowedSize )
                 sizeTree.SetSize( eData.myC3d.Value( 0.6*pIt2->myU + 0.4*pIt1->myU ), allowedSize );
             }
             pIt1->mySegSize = allowedSize;
           }
           ++pIt1;
-          if ( & (*pIt1) == & eData.Last() )
-            avoidPnt = & eData.Last().myP;
-          else
-            avoidPnt = NULL;
+          avoidPnt = ( pIt1 == pItLast ) ? & eData.Last().myP : NULL;
 
           if ( iLoop > 20 )
           {
-#ifdef _DEBUG_
-            cout << "Infinite loop in AdaptiveAlgo::Compute()" << endl;
-#endif
+            if(SALOME::VerbosityActivated())
+              cout << "Infinite loop in AdaptiveAlgo::Compute()" << endl;
+
             sizeDecreased = false;
             break;
           }
@@ -1355,7 +1353,7 @@ bool AdaptiveAlgo::makeSegments()
 
   vector< double > nbSegs, params;
 
-  for ( int iE = 0; iE < myEdges.size(); ++iE )
+  for ( size_t iE = 0; iE < myEdges.size(); ++iE )
   {
     EdgeData& eData = myEdges[ iE ];
 
@@ -1366,13 +1364,13 @@ bool AdaptiveAlgo::makeSegments()
       edgeMinSize = Min( edgeMinSize,
                          Min( pIt1->mySegSize, mySizeTree->GetSize( pIt1->myP )));
 
-    const double f = eData.myC3d.FirstParameter(), l = eData.myC3d.LastParameter();
+    const double      f = eData.myC3d.FirstParameter(), l = eData.myC3d.LastParameter();
     const double parLen = l - f;
     const int  nbDivSeg = 5;
-    int           nbDiv = Max( 1, int ( eData.myLength / edgeMinSize * nbDivSeg ));
+    size_t        nbDiv = Max( 1, int ( eData.myLength / edgeMinSize * nbDivSeg ));
 
     // compute nb of segments
-    bool toRecompute = true;
+    bool  toRecompute = true;
     double maxSegSize = 0;
     size_t i = 1, segCount;
     //cout << "E " << theMesh.GetMeshDS()->ShapeToIndex( eData.Edge() ) << endl;
@@ -1430,7 +1428,7 @@ bool AdaptiveAlgo::makeSegments()
     }
 
     // compute parameters of nodes
-    int nbSegFinal = Max( 1, int(floor( nbSegs.back() + 0.5 )));
+    size_t nbSegFinal = Max( 1, int(floor( nbSegs.back() + 0.5 )));
     double fact = nbSegFinal / nbSegs.back();
     if ( maxSegSize / fact > myHyp->GetMaxSize() )
       fact = ++nbSegFinal / nbSegs.back();
@@ -1503,7 +1501,7 @@ bool AdaptiveAlgo::Evaluate(SMESH_Mesh &         theMesh,
 
   for ( ; edExp.More(); edExp.Next() )
   {
-    const TopoDS_Edge & edge = TopoDS::Edge( edExp.Current() );
+    //const TopoDS_Edge & edge = TopoDS::Edge( edExp.Current() );
     StdMeshers_Regular_1D::Evaluate( theMesh, theShape, theResMap );
   }
   return true;