Salome HOME
updated copyright message
[plugins/blsurfplugin.git] / src / BLSURFPlugin / BLSURFPlugin_Attractor.cxx
index 554630954476045e2657ce51d5772d380090d5ac..c279274c6d08f2c7379f361a182ee21ab66a0b8d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2015  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2023  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
@@ -44,13 +44,14 @@ BLSURFPlugin_Attractor::BLSURFPlugin_Attractor ()
   : _face(),
   _attractorShape(),
   _attEntry(),
-  _gridU(0),
-  _gridV(0),
   _vectU(),
   _vectV(),
   _DMap(),
   _known(),
   _trial(),
+  _type(-1),
+  _gridU(0),
+  _gridV(0),
   _u1 (0.),
   _u2 (0.),
   _v1 (0.),
@@ -59,40 +60,40 @@ BLSURFPlugin_Attractor::BLSURFPlugin_Attractor ()
   _endSize(-1),
   _actionRadius(-1),
   _constantRadius(-1),
-  _type(-1),
   _isMapBuilt(false),
   _isEmpty(true){ MESSAGE("construction of a void attractor"); }
 
-BLSURFPlugin_Attractor::BLSURFPlugin_Attractor (const TopoDS_Face& Face, const TopoDS_Shape& Attractor, const std::string& attEntry) 
+BLSURFPlugin_Attractor::BLSURFPlugin_Attractor (const TopoDS_Face& Face, const TopoDS_Shape& Attractor, const std::string& attEntry)
   : _face(),
-  _attractorShape(),
-  _attEntry(attEntry),
-  _gridU(),
-  _gridV(),
-  _vectU(),
-  _vectV(),
-  _DMap(),
-  _known(),
-  _trial(),
-  _u1 (0.),
-  _u2 (0.),
-  _v1 (0.),
-  _v2 (0.),
-  _startSize(-1),
-  _endSize(-1),
-  _actionRadius(-1),
-  _constantRadius(-1),
-  _type(0),
-  _isMapBuilt(false),
-  _isEmpty(false)
+    _attractorShape(),
+    _attEntry(attEntry),
+    _vectU(),
+    _vectV(),
+    _DMap(),
+    _known(),
+    _trial(),
+    _type(0),
+    _gridU(),
+    _gridV(),
+    _u1 (0.),
+    _u2 (0.),
+    _v1 (0.),
+    _v2 (0.),
+    _startSize(-1),
+    _endSize(-1),
+    _actionRadius(-1),
+    _constantRadius(-1),
+    _isMapBuilt(false),
+    _isEmpty(false)
 {
   _face = Face;
   _attractorShape = Attractor;
-  
+
   init();
 }
 
-bool BLSURFPlugin_Attractor::init(){ 
+bool BLSURFPlugin_Attractor::init()
+{
   Standard_Real u0,v0;
   int i,j,i0,j0 ;
   _known.clear();
@@ -119,7 +120,7 @@ bool BLSURFPlugin_Attractor::init(){
       return true;
     }
   }
-  
+
   // Calculation of the bounds of the face
   ShapeAnalysis::GetFaceUVBounds(_face,_u1,_u2,_v1,_v2);
 
@@ -132,7 +133,7 @@ bool BLSURFPlugin_Attractor::init(){
   for (j=0; j<=_gridV; j++){
     _vectV.push_back(_v1+j*(_v2-_v1)/_gridV) ;
   }
-  
+
   // Initialization of _DMap and _known
   std::vector<double> temp(_gridV+1,std::numeric_limits<double>::infinity());  // Set distance of all "far" points to Infinity 
   for (i=0; i<=_gridU; i++){
@@ -159,11 +160,11 @@ bool BLSURFPlugin_Attractor::init(){
     gp_Pnt P = BRep_Tool::Pnt(aVertex);
     GeomAPI_ProjectPointOnSurf projector( P, aSurf );
     projector.LowerDistanceParameters(u0,v0);
-    i0 = floor ( (u0 - _u1) * _gridU / (_u2 - _u1) + 0.5 );
-    j0 = floor ( (v0 - _v1) * _gridV / (_v2 - _v1) + 0.5 );
+    i0 = int( floor ( (u0 - _u1) * _gridU / (_u2 - _u1) + 0.5 ));
+    j0 = int( floor ( (v0 - _v1) * _gridV / (_v2 - _v1) + 0.5 ));
     TPnt[0]=0.;                                                                // Set the distance of the starting point to 0.
-    TPnt[1]=i0;
-    TPnt[2]=j0;
+    TPnt[1]=double( i0 );
+    TPnt[2]=double( j0 );
     _DMap[i0][j0] = 0.;
     _trial.insert(TPnt);                                                       // Move starting point to _trial
   }
@@ -171,23 +172,42 @@ bool BLSURFPlugin_Attractor::init(){
   return true;
 }
 
-void BLSURFPlugin_Attractor::edgeInit(Handle(Geom_Surface) theSurf, const TopoDS_Edge& anEdge){
+// check that i and j are inside the bounds of the grid to avoid out of bounds errors
+// in affectation of the grid's vectors
+void BLSURFPlugin_Attractor::avoidOutOfBounds(int& i, int& j)
+{
+  if (i > _gridU)
+    i = _gridU;
+  if (i < 0)
+    i = 0;
+  if (j > _gridV)
+    j = _gridV;
+  if (j < 0)
+    j = 0;
+}
+
+void BLSURFPlugin_Attractor::edgeInit(Handle(Geom_Surface) theSurf, const TopoDS_Edge& anEdge)
+{
   gp_Pnt2d P2;
   double first;
   double last;
-  int i,j,i0,j0;
+  int i,i0,j0;
   Trial_Pnt TPnt(3,0);
   Handle(Geom2d_Curve) aCurve2d; 
   Handle(Geom_Curve) aCurve3d = BRep_Tool::Curve (anEdge, first, last);
   ShapeConstruct_ProjectCurveOnSurface curveProjector;
   curveProjector.Init(theSurf, Precision::Confusion());
-  curveProjector.PerformAdvanced (aCurve3d, first, last, aCurve2d);
-  
+  curveProjector.Perform (aCurve3d, first, last, aCurve2d);
+
   int N = 1200;
   for (i=0; i<=N; i++){
     P2 = aCurve2d->Value(first + i * (last-first) / N);
-    i0 = floor( (P2.X() - _u1) * _gridU / (_u2 - _u1) + 0.5 );
-    j0 = floor( (P2.Y() - _v1) * _gridV / (_v2 - _v1) + 0.5 );
+    i0 = int(floor( (P2.X() - _u1) * _gridU / (_u2 - _u1) + 0.5 ));
+    j0 = int(floor( (P2.Y() - _v1) * _gridV / (_v2 - _v1) + 0.5 ));
+
+    // Avoid out of bounds errors when the ends of the edge are outside the face
+    avoidOutOfBounds(i0, j0);
+
     TPnt[0] = 0.;
     TPnt[1] = i0;
     TPnt[2] = j0;
@@ -197,7 +217,8 @@ void BLSURFPlugin_Attractor::edgeInit(Handle(Geom_Surface) theSurf, const TopoDS
 }  
 
 
-void BLSURFPlugin_Attractor::SetParameters(double Start_Size, double End_Size, double Action_Radius, double Constant_Radius){
+void BLSURFPlugin_Attractor::SetParameters(double Start_Size, double End_Size, double Action_Radius, double Constant_Radius)
+{
   _startSize = Start_Size;
   _endSize = End_Size;
   _actionRadius = Action_Radius;
@@ -209,12 +230,15 @@ double BLSURFPlugin_Attractor::_distanceFromPoint(double u, double v)
   return _attractorPnt.Distance( _plane->Value( u, v ));
 }
 
-double BLSURFPlugin_Attractor::_distanceFromMap(double u, double v){
-  
+double BLSURFPlugin_Attractor::_distanceFromMap(double u, double v)
+{
   //   MG-CADSurf seems to perform a linear interpolation so it's sufficient to give it a non-continuous distance map
-  int i = floor ( (u - _u1) * _gridU / (_u2 - _u1) + 0.5 );
-  int j = floor ( (v - _v1) * _gridV / (_v2 - _v1) + 0.5 );
+  int i = int(floor ( (u - _u1) * _gridU / (_u2 - _u1) + 0.5 ));
+  int j = int(floor ( (v - _v1) * _gridV / (_v2 - _v1) + 0.5 ));
   
+  // Avoid out of bounds errors in _DMap
+  avoidOutOfBounds(i, j);
+
   return _DMap[i][j];
 }
 
@@ -238,17 +262,18 @@ double BLSURFPlugin_Attractor::GetSize(double u, double v)
       }
       break;
     case TYPE_LIN:
-        return _startSize + ( 0.5 * (attrDist - _constantRadius + abs(attrDist - _constantRadius)) ) ;
+        return _startSize + ( 0.5 * (attrDist - _constantRadius + fabs(attrDist - _constantRadius)) ) ;
       break;
   }
+  return -1;
 }
 
 
-void BLSURFPlugin_Attractor::BuildMap() { 
-  
+void BLSURFPlugin_Attractor::BuildMap()
+{
   MESSAGE("building the map");
-  int i, j, k, n;  
-  int count = 0;
+  int i, j, k, n;
+  //int count = 0;
   int ip, jp, kp, np;
   int i0, j0;
   gp_Pnt P;
@@ -263,26 +288,28 @@ void BLSURFPlugin_Attractor::BuildMap() {
   TTrialSet::iterator min;
   TTrialSet::iterator found;
   Handle(Geom_Surface) aSurf = BRep_Tool::Surface(_face);
-  
+
   // While there are points in "Trial" (representing a kind of advancing front), loop on them -----------------------------------------------------------
   while (_trial.size() > 0 ) {
     min = _trial.begin();                        // Get trial point with min distance from start
-    i0 = (*min)[1];
-    j0 = (*min)[2];
+    i0 = int( (*min)[1] );
+    j0 = int( (*min)[2] );
+    // Avoid out of bounds errors in _known affectations
+    avoidOutOfBounds(i0, j0);
     _known[i0][j0] = true;                       // Move it to "Known"
     _trial.erase(min);                           // Remove it from "Trial"
-    
+
     // Loop on neighbours of the trial min --------------------------------------------------------------------------------------------------------------
-    for (i=i0 - 1 ; i <= i0 + 1 ; i++){ 
-      if (!aSurf->IsUPeriodic()){                          // Periodic conditions in U  
+    for (i=i0 - 1 ; i <= i0 + 1 ; i++){
+      if (!aSurf->IsUPeriodic()){                          // Periodic conditions in U
         if (i > _gridU ){
           break; }
         else if (i < 0){
           i++; }
       }
       ip = (i + _gridU + 1) % (_gridU+1);                  // We get a periodic index :
-      for (j=j0 - 1 ; j <= j0 + 1 ; j++){                  //    ip=modulo(i,N+2) so that  i=-1->ip=N; i=0 -> ip=0 ; ... ; i=N+1 -> ip=0;  
-        if (!aSurf->IsVPeriodic()){                        // Periodic conditions in V . 
+      for (j=j0 - 1 ; j <= j0 + 1 ; j++){                  //    ip=modulo(i,N+2) so that  i=-1->ip=N; i=0 -> ip=0 ; ... ; i=N+1 -> ip=0;
+        if (!aSurf->IsVPeriodic()){                        // Periodic conditions in V .
           if (j > _gridV ){
             break; }
           else if (j < 0){
@@ -290,23 +317,23 @@ void BLSURFPlugin_Attractor::BuildMap() {
           }
         }
         jp = (j + _gridV + 1) % (_gridV+1);
-      
+
         if (!_known[ip][jp]){                              // If the distance is not known yet
           aSurf->D1(_vectU[ip],_vectV[jp],P,D1U,D1V);      // Calculate the metric tensor at (i,j)
-          // G(i,j)  =  | ||dS/du||**2          *     | 
+          // G(i,j)  =  | ||dS/du||**2          *     |
           //            | <dS/du,dS/dv>  ||dS/dv||**2 |
-          Guu = D1U.X()*D1U.X() +  D1U.Y()*D1U.Y() + D1U.Z()*D1U.Z();    // Guu = ||dS/du||**2    
-          Gvv = D1V.X()*D1V.X() +  D1V.Y()*D1V.Y() + D1V.Z()*D1V.Z();    // Gvv = ||dS/dv||**2           
-          Guv = D1U.X()*D1V.X() +  D1U.Y()*D1V.Y() + D1U.Z()*D1V.Z();    // Guv = Gvu = < dS/du,dS/dv > 
-          D_Ref = _DMap[ip][jp];                           // Set a ref. distance of the point to its value in _DMap 
+          Guu = D1U.X()*D1U.X() +  D1U.Y()*D1U.Y() + D1U.Z()*D1U.Z();    // Guu = ||dS/du||**2
+          Gvv = D1V.X()*D1V.X() +  D1V.Y()*D1V.Y() + D1V.Z()*D1V.Z();    // Gvv = ||dS/dv||**2
+          Guv = D1U.X()*D1V.X() +  D1U.Y()*D1V.Y() + D1U.Z()*D1V.Z();    // Guv = Gvu = < dS/du,dS/dv >
+          D_Ref = _DMap[ip][jp];                           // Set a ref. distance of the point to its value in _DMap
           TPnt[0] = D_Ref;                                 // (may be infinite or uncertain)
           TPnt[1] = ip;
           TPnt[2] = jp;
           Dist_changed = false;
-          
+
           // Loop on neighbours to calculate the min distance from them ---------------------------------------------------------------------------------
           for (k=i - 1 ; k <= i + 1 ; k++){
-            if (!aSurf->IsUPeriodic()){                              // Periodic conditions in U  
+            if (!aSurf->IsUPeriodic()){                              // Periodic conditions in U
               if(k > _gridU ){
                 break;
               }
@@ -314,15 +341,15 @@ void BLSURFPlugin_Attractor::BuildMap() {
                 k++; }
             }
             kp = (k + _gridU + 1) % (_gridU+1);                      // periodic index
-            for (n=j - 1 ; n <= j + 1 ; n++){ 
-              if (!aSurf->IsVPeriodic()){                            // Periodic conditions in V 
-                if(n > _gridV){   
+            for (n=j - 1 ; n <= j + 1 ; n++){
+              if (!aSurf->IsVPeriodic()){                            // Periodic conditions in V
+                if(n > _gridV){
                   break;
                 }
                 else if (n < 0){
                   n++; }
               }
-              np = (n + _gridV + 1) % (_gridV+1);                    
+              np = (n + _gridV + 1) % (_gridV+1);
               if (_known[kp][np]){                                   // If the distance of the neighbour is known
                                                                      // Calculate the distance from (k,n)
                 du = (k-i) * (_u2 - _u1) / _gridU;
@@ -335,8 +362,8 @@ void BLSURFPlugin_Attractor::BuildMap() {
               }
             }
           } // End of the loop on neighbours --------------------------------------------------------------------------------------------------------------
-          
-          if (Dist_changed) {                              // If distance has been updated, update _trial 
+
+          if (Dist_changed) {                              // If distance has been updated, update _trial
             found=_trial.find(TPnt);
             if (found != _trial.end()){
               _trial.erase(found);                         // Erase the point if it was already in _trial