]> SALOME platform Git repositories - plugins/blsurfplugin.git/commitdiff
Salome HOME
rnc: add a class for the management of attractors in blsurf_plugin
authorgdd <gdd>
Wed, 2 Feb 2011 10:36:36 +0000 (10:36 +0000)
committergdd <gdd>
Wed, 2 Feb 2011 10:36:36 +0000 (10:36 +0000)
src/BLSURFPlugin/BLSURFPlugin_Attractor.cxx [new file with mode: 0644]
src/BLSURFPlugin/BLSURFPlugin_Attractor.hxx [new file with mode: 0644]

diff --git a/src/BLSURFPlugin/BLSURFPlugin_Attractor.cxx b/src/BLSURFPlugin/BLSURFPlugin_Attractor.cxx
new file mode 100644 (file)
index 0000000..ccce23a
--- /dev/null
@@ -0,0 +1,146 @@
+BLSURFPlugin_Attractor::BLSURFPlugin_Attractor (TopoDS_Face Face, TopoDS_Shape Attractor, int MapGrid){
+  _face = Face;
+  _attractorShape = Attractor;
+  _mapGrid = MapGrid;
+  
+  init();
+}
+
+bool BLSURFPlugin_Attractor::init(){ 
+  
+  _known.clear();
+  _trial.clear();
+  Handle(Geom_Surface) aSurf = BRep_Tool::Surface(_face);
+  TPnt Trial_Pnt(0,0,0); 
+  
+  // Discretization of the parameters
+  aSurf->Bounds(_u1, _u2, _v1, _v2);   // unusable in the generic case because the surface may be infinite (ok for prototype on a Sphere)
+  double Ustep = (_u2 - _u1) / _mapGrid;
+  double Vstep = (_v2 - _v1) / _mapGrid; 
+  for (i=0; i<=_mapGrid; i++){
+    _vectU.push_back(_u1+i*(_u2-_u1)/_mapGrid) ;
+    _vectV.push_back(_u1+i*(_u2-_u1)/_mapGrid) ;
+  }
+
+  // Determination of the starting point
+  int i0 = floor ( (u0 - _u1) * _mapGrid / (_u2 - _u1) + 0.5 );
+  int j0 = floor ( (v0 - _v1) * _mapGrid / (_v2 - _v1) + 0.5 );
+  TPnt.dist=0.;                // Set distance to 0.
+  TPnt.Ti=i0;
+  TPnt.Tj=j0;
+  _trial.insert(TPnt);         // Move starting point to _trial
+  
+  // Initialization of _DMap
+  std:vector<double> temp(_mapGrid+1,numeric_limits<double>::infinity()); // Set distance of all "far" points to Infinity
+  for (i=0; i<=_mapGrid; i++){
+    DMap.push_back(temp);
+  }
+  _DMap[i0][j0] = 0.;         // Set distance of starting point to 0.
+  
+  _buildMap();                // Computes the distance for all points of the discrete surface
+}
+
+double BLSURFPlugin_BLSURF::GetSize(double u, double v){
+  int i = floor ( (u - _u1) * _mapGrid / (_u2 - _u1) + 0.5 );
+  int j = floor ( (v - _v1) * _mapGrid / (_v2 - _v1) + 0.5 );
+  return _DMap[i][j];         // more generally: function of _DMap 
+
+}
+
+bool BLSURFPlugin_Attractor::_buildMap(){  
+  int i, j, k, n;        
+  int ip, jp, kp, np; 
+  gp_Pnt P;
+  gp_Vec D1U,D1V;
+  double Guu, Gvv;         //Diagonal components of the local metric tensor
+  double du, dv;
+  double D_Ref = 0.;
+  double Dist = 0.;
+  bool Dist_changed = false;
+  Current_Pnt = IJ_Pnt(0,0);
+  TPnt Trial_Pnt(0,0,0); 
+  TTrialSet::iterator min;
+  
+  while (_trial.size() > 0){
+      
+    min = _trial.begin();       // Get trial point with min distance from start
+    i0 = min->Ti;
+    j0 = min->Tj;
+    Current_Pnt.Pi = i0;        // Define it as the current point
+    Current_Pnt.Pj = j0; 
+    _known.insert(Current_Pnt); // Move it to _known and remove it from _trial
+    _trial.erase(min);
+    // ------------------------ // Loop on neighbours of the trial min 
+    for (i=i0 - 1 ; i < i0 + 1 ; i++){           
+      if (!aSurf->IsUPeriodic()){               // Periodic conditions in U    
+       if (i > _mapGrid + 1){
+         break; }
+       else if (i < 0){
+         i++; }
+       }
+      ip = i % _mapGrid+2;                      // We get a periodic index ip=modulo(i,N+2) so that  i=-1->ip=N+1; i=0 -> ip=0 ; ... ; i=N+2 -> ip=0;
+      for (j=j0 - 1 ; j < j0 + 1 ; j++){   
+       if (!aSurf->IsVPeriodic()){             // Periodic conditions in V .  
+         if (j > _mapGrid + 1){
+           break; }
+         else if (j < 0){
+           j++; }
+       }
+       jp = j % _mapGrid+2;
+       Current_Pnt.Pi = ip;                    // Define the neighbour as current point
+       Current_Pnt.Pj = jp;
+       if (_known.find( Current_Pnt ) == _known.end()){  // If the distance is not known
+         aSurf->D1(_vectU[i],_vectV[j],P,D1U,D1V);       // Calculate the metric at (i,j)      
+         Guu = D1U.X()*D1U.X() +  D1U.Y()*D1U.Y() + D1U.Z()*D1U.Z();  // Guu = ||dS/du||**2    G(i,j)= | ||dS/du||**2        0     | assuming that the isolines are orthogonal in 3D space
+         Gvv = D1V.X()*D1V.X() +  D1V.Y()*D1V.Y() + D1V.Z()*D1V.Z();  // Gvv = ||dS/dv||**2            |    0         ||dS/dv||**2 |
+         D_Ref = DMap[ip][jp];                           // Set a ref. distance to the value in DMap (may be infinite or uncertain)
+         TPnt.dist = D_Ref;                              // Store the point as a trial point
+         TPnt.Ti = ip;
+         TPnt.Tj = jp;
+         // -------------------------------------------- // Calculate the min distance among the neighbours
+         for (k=i - 1 ; k < i + 1 ; k++){
+           if (!aSurf->IsUPeriodic()){                   // Periodic conditions in U  
+             if(k > _mapGrid + 1){
+               break; }
+             else if (k < 0){
+               k++; }
+             }
+           kp = k % _mapGrid+2;                          // periodic index
+           for (n=j - 1 ; n < j + 1 ; n++){ 
+             if (!aSurf->IsUPeriodic()){                 // Periodic conditions in V 
+               if(n > _mapGrid + 1){
+                 break; }
+               else if (n < 0){
+                 n++; }
+             }
+             np = k % _mapGrid+2;
+             Current_Pnt.Pi = kp;
+             Current_Pnt.Pj = np;
+             if (_known.find( Current_Pnt ) != _known.end()){  // If distance of the neighbour is known
+                                                               // Calculate the distance from (k,n)
+               du = (k-i) * Ustep;
+               dv = (n-j) * Vstep;
+               Dist = _DMap[kp][np] + Guu * du*du + Gvv * dv*dv;   // ds**2 = du'Gdu + dv'Gdv (we assume Guv=Gvu=0)
+               if (Dist < D_Ref) {                             // If smaller than ref. distance -> update ref. distance
+                 D_Ref = Dist;
+                 Dist_changed = true;
+               }
+             }
+           }
+         }
+         if (Dist_changed) {       // If distance has been updated, update _trial 
+           _trial.erase(TPnt);
+           TPnt.dist = D_Ref;
+           TPnt.Ti = i;
+           TPnt.Tj = j;
+           _trial.insert(TPnt);
+         }
+       } // if
+      } // for
+    } // for
+  } // while (_trial)
+  
+} // _buildMap()
+
+
+
diff --git a/src/BLSURFPlugin/BLSURFPlugin_Attractor.hxx b/src/BLSURFPlugin/BLSURFPlugin_Attractor.hxx
new file mode 100644 (file)
index 0000000..ece0508
--- /dev/null
@@ -0,0 +1,127 @@
+//  Copyright (C) 2007-2010  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
+//  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.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// ---
+// File    : BLSURFPlugin_Attractor.hxx
+// Authors : Renaud Nédélec (OCC)
+// ---
+//
+#ifndef _BLSURFPlugin_Attractor_HXX_
+#define _BLSURFPlugin_Attractor_HXX_
+
+#include <vector>
+#include <map>
+#include <set>
+#include <stdexcept>
+#include <string>
+
+
+
+class BLSURFPlugin_Attractor {
+  public:
+    BLSURFPlugin_Attractor (TopoDS_Face Face, TopoDS_Shape Attractor, int MapGrid);
+    bool init();                              // Calculates the discrete points correponding to attractor, initialises the map and calls _buildMap
+
+    double GetSize (double u, double v);
+    TopoDS_Face GetFace(){ return _face;}
+    TopoDS_Shape GetAttractor(){ return _attractorShape;}
+    bool SetAttractor(TopoDS_Shape Attractor){ _attractorShape = Attractor; }
+    
+    typedef std::vector<double> TDiscreteParam;
+    typedef std::vector< std::vector<double> > TDistMap;
+    typedef std::set< IJ_Pnt, IJ_comp > TPointSet;
+    typedef std::set< Trial_Pnt, Trial_comp> TTrialSet;
+          
+  private:
+    
+    TopoDS_Face       _face;
+    TopoDS_Shape      _attractorShape;
+    TDiscreteParam    _vectU;
+    TDiscreteParam    _vectV;
+    TDistMap          _DMap;
+    TPointSet         _known;
+    TTrialSet         _trial;
+    int               _mapGrid;              // Number of grid points in U and V directions
+    double            _u1, _u2, _v1, _v2;    // Bounds of the parametric space of the face 
+    int               _i0, _j0;              // Indices of the starting point
+    
+    bool              _buildMap();           // Builds the map of distances between source point and any point (u,v)
+};    
+
+class IJ_Pnt{
+  public:
+    IJ_Pnt(int i,int j){ 
+      Pi=i;
+      Pj=j;
+    } 
+    int Pi;
+    int Pj;
+};
+
+class IJ_comp{
+  bool operator() (const IJ_Pnt p1, const IJ_Pnt p2) {
+    if (&p1 && &p2)
+      return ((p1.Pi < p2.Pi) && (p1.Pj < p2.Pj));
+    else 
+      return (&p1 < &p2);
+  }
+};
+
+class Trial_Pnt{
+  public:
+    Trial_Pnt(int i,int j,double d){ 
+      Ti=i;
+      Tj=j;
+      dist=d;
+    }
+    int Ti;
+    int Tj;
+    double dist;
+}; 
+
+class Trial_comp {  
+  bool operator() (const Trial_Pnt me, const Trial_Pnt other) const { 
+    return (&me && &other) ? (me.dist < other.dist) : (&me < &other); 
+  } 
+};
+  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#endif