From 4e9df4ee4c0b7dd615b53899fb3283b083f1fc1e Mon Sep 17 00:00:00 2001 From: gdd Date: Wed, 2 Feb 2011 10:36:36 +0000 Subject: [PATCH] rnc: add a class for the management of attractors in blsurf_plugin --- src/BLSURFPlugin/BLSURFPlugin_Attractor.cxx | 146 ++++++++++++++++++++ src/BLSURFPlugin/BLSURFPlugin_Attractor.hxx | 127 +++++++++++++++++ 2 files changed, 273 insertions(+) create mode 100644 src/BLSURFPlugin/BLSURFPlugin_Attractor.cxx create mode 100644 src/BLSURFPlugin/BLSURFPlugin_Attractor.hxx diff --git a/src/BLSURFPlugin/BLSURFPlugin_Attractor.cxx b/src/BLSURFPlugin/BLSURFPlugin_Attractor.cxx new file mode 100644 index 0000000..ccce23a --- /dev/null +++ b/src/BLSURFPlugin/BLSURFPlugin_Attractor.cxx @@ -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 temp(_mapGrid+1,numeric_limits::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 index 0000000..ece0508 --- /dev/null +++ b/src/BLSURFPlugin/BLSURFPlugin_Attractor.hxx @@ -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 +#include +#include +#include +#include + + + +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 TDiscreteParam; + typedef std::vector< std::vector > 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 -- 2.39.2