--- /dev/null
+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()
+
+
+
--- /dev/null
+// 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