]> SALOME platform Git repositories - plugins/blsurfplugin.git/commitdiff
Salome HOME
2625: [CEA 1195] Several attractors per face
authoreap <eap@opencascade.com>
Fri, 1 Aug 2014 11:20:30 +0000 (15:20 +0400)
committereap <eap@opencascade.com>
Fri, 1 Aug 2014 11:20:30 +0000 (15:20 +0400)
src/BLSURFPlugin/BLSURFPlugin_Attractor.cxx
src/BLSURFPlugin/BLSURFPlugin_Attractor.hxx
src/BLSURFPlugin/BLSURFPlugin_BLSURF.cxx
src/BLSURFPlugin/BLSURFPlugin_Hypothesis.cxx
src/BLSURFPlugin/BLSURFPlugin_Hypothesis.hxx
src/GUI/BLSURFPluginGUI_HypothesisCreator.cxx
src/GUI/BLSURFPluginGUI_HypothesisCreator.h

index 7a2b2b9b580dd5991bbb46efe2f7d271775b67da..e5366dc047a222a224b75b4364f11351034efdc2 100644 (file)
 #include <cmath>
 
 // cascade include
-#include "ShapeAnalysis.hxx"
-#include "ShapeConstruct_ProjectCurveOnSurface.hxx"
+#include <ShapeAnalysis.hxx>
+#include <ShapeConstruct_ProjectCurveOnSurface.hxx>
 #include <Precision.hxx>
+#include <GeomLib_IsPlanarSurface.hxx>
 
 BLSURFPlugin_Attractor::BLSURFPlugin_Attractor ()
   : _face(),
@@ -97,6 +98,27 @@ bool BLSURFPlugin_Attractor::init(){
   _known.clear();
   _trial.clear();
   Handle(Geom_Surface) aSurf = BRep_Tool::Surface(_face);
+
+  _distance = &BLSURFPlugin_Attractor::_distanceFromMap;
+
+  if ( GeomLib_IsPlanarSurface( aSurf ).IsPlanar() &&
+       _attractorShape.ShapeType() == TopAbs_VERTEX )
+  {
+    // a specific case, the map is not needed
+    gp_Pnt P = BRep_Tool::Pnt( TopoDS::Vertex( _attractorShape ));
+    GeomAPI_ProjectPointOnSurf projector( P, aSurf );
+    if ( projector.IsDone() && projector.NbPoints() == 1 )
+    {
+      projector.LowerDistanceParameters(u0,v0);
+
+      _attractorPnt = aSurf->Value( u0,v0 );
+      _plane        = aSurf;
+      _distance     = &BLSURFPlugin_Attractor::_distanceFromPoint;
+      _isMapBuilt   = true;
+      _isEmpty      = false;
+      return true;
+    }
+  }
   
   // Calculation of the bounds of the face
   ShapeAnalysis::GetFaceUVBounds(_face,_u1,_u2,_v1,_v2);
@@ -182,7 +204,12 @@ void BLSURFPlugin_Attractor::SetParameters(double Start_Size, double End_Size, d
   _constantRadius = Constant_Radius;
 }
 
-double BLSURFPlugin_Attractor::_distance(double u, double v){
+double BLSURFPlugin_Attractor::_distanceFromPoint(double u, double v)
+{
+  return _attractorPnt.Distance( _plane->Value( u, v ));
+}
+
+double BLSURFPlugin_Attractor::_distanceFromMap(double u, double v){
   
   //   BLSURF 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 );
@@ -191,9 +218,10 @@ double BLSURFPlugin_Attractor::_distance(double u, double v){
   return _DMap[i][j];
 }
 
-
-double BLSURFPlugin_Attractor::GetSize(double u, double v){   
-  double myDist = 0.5 * (_distance(u,v) - _constantRadius + fabs(_distance(u,v) - _constantRadius));
+double BLSURFPlugin_Attractor::GetSize(double u, double v)
+{
+  const double attrDist = (this->*_distance)(u,v);
+  const double myDist = 0.5 * (attrDist - _constantRadius + fabs(attrDist - _constantRadius));
   switch(_type)
   {
     case TYPE_EXP:
@@ -210,13 +238,13 @@ double BLSURFPlugin_Attractor::GetSize(double u, double v){
       }
       break;
     case TYPE_LIN:
-        return _startSize + ( 0.5 * (_distance(u,v) - _constantRadius + abs(_distance(u,v) - _constantRadius)) ) ;
+        return _startSize + ( 0.5 * (attrDist - _constantRadius + abs(attrDist - _constantRadius)) ) ;
       break;
   }
 }
 
 
-void BLSURFPlugin_Attractor::BuildMap(){ 
+void BLSURFPlugin_Attractor::BuildMap() 
   
   MESSAGE("building the map");
   int i, j, k, n;  
@@ -237,7 +265,7 @@ void BLSURFPlugin_Attractor::BuildMap(){
   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 ){
+  while (_trial.size() > 0 ) {
     min = _trial.begin();                        // Get trial point with min distance from start
     i0 = (*min)[1];
     j0 = (*min)[2];
index 693cc67326ee834e99cefa6c10747c2fa2013fc2..064006d5f46997a4539d23e3ad949a287c2ad7ab 100644 (file)
@@ -138,8 +138,14 @@ class BLSURFPlugin_Attractor {
     
     bool              _isMapBuilt;
     bool              _isEmpty;
+
+  // data of a specific case: a point attractor on a plane
+  Handle(Geom_Surface) _plane;
+  gp_Pnt               _attractorPnt;
     
-    double            _distance(double u, double v);            // Retrieve the value of the distance map at point (u,v) of the parametric space of _face
+  double            (BLSURFPlugin_Attractor::*_distance)(double u, double v);            // Retrieve the value of the distance map at point (u,v) of the parametric space of _face
+  double            _distanceFromMap(double u, double v);
+  double            _distanceFromPoint(double u, double v);
 };    
 
 #endif
index cc97f343a6afac36cd2e54c7e3d144f743e54ab3..559cb797980247ffc1dd7cc6222487d92db25702 100644 (file)
@@ -201,6 +201,7 @@ PyObject * newPyStdOut( std::string& out )
 ////////////////////////END PYTHON///////////////////////////
 
 //////////////////MY MAPS////////////////////////////////////////
+namespace {
 TopTools_IndexedMapOfShape FacesWithSizeMap;
 std::map<int,string> FaceId2SizeMap;
 TopTools_IndexedMapOfShape EdgesWithSizeMap;
@@ -212,9 +213,11 @@ std::map<int,PyObject*> FaceId2PythonSmp;
 std::map<int,PyObject*> EdgeId2PythonSmp;
 std::map<int,PyObject*> VertexId2PythonSmp;
 
+typedef std::map<int, std::vector< BLSURFPlugin_Attractor* > > TId2ClsAttractorVec;
+TId2ClsAttractorVec FaceId2ClassAttractor;
+TId2ClsAttractorVec FaceIndex2ClassAttractor;
 std::map<int,std::vector<double> > FaceId2AttractorCoords;
-std::map<int,BLSURFPlugin_Attractor*> FaceId2ClassAttractor;
-std::map<int,BLSURFPlugin_Attractor*> FaceIndex2ClassAttractor;
+int theNbAttractors;
 
 TopTools_IndexedMapOfShape FacesWithEnforcedVertices;
 std::map< int, BLSURFPlugin_Hypothesis::TEnfVertexCoordsList > FaceId2EnforcedVertexCoords;
@@ -225,7 +228,7 @@ bool HasSizeMapOnFace=false;
 bool HasSizeMapOnEdge=false;
 bool HasSizeMapOnVertex=false;
 //bool HasAttractorOnFace=false;
-
+}
 //=============================================================================
 /*!
  *
@@ -1281,6 +1284,7 @@ void BLSURFPlugin_BLSURF::SetParameters(
     //  - build the map here for each face with an attractor set and only if the attractor shape as changed since the last call to _buildmap()
     //  -> define a bool _mapbuilt in the class that is set to false by default and set to true when calling _buildmap()  OK
 
+      theNbAttractors = 0;
     const BLSURFPlugin_Hypothesis::TAttractorMap class_attractors = BLSURFPlugin_Hypothesis::GetClassAttractorEntries(hyp);
     int key=-1;
     BLSURFPlugin_Hypothesis::TAttractorMap::const_iterator AtIt = class_attractors.begin();
@@ -1288,6 +1292,8 @@ void BLSURFPlugin_BLSURF::SetParameters(
       if ( !AtIt->second->Empty() ) {
        // MESSAGE("cadsurf_set_attractor(): " << AtIt->first << " = " << AtIt->second);
         GeomShape = entryToShape(AtIt->first);
+        if ( !SMESH_MesherHelper::IsSubShape( GeomShape, theGeomShape ))
+          continue;
         AttShape = AtIt->second->GetAttractorShape();
         GeomType  = GeomShape.ShapeType();
         // Group Management
@@ -1307,15 +1313,10 @@ void BLSURFPlugin_BLSURF::SetParameters(
            || AttShape.ShapeType() == TopAbs_COMPOUND) ){
             HasSizeMapOnFace = true;
 
-            if (! FacesWithSizeMap.Contains(TopoDS::Face(GeomShape)) ) {
-                key = FacesWithSizeMap.Add(TopoDS::Face(GeomShape) );
-            }
-            else {
-              key = FacesWithSizeMap.FindIndex(TopoDS::Face(GeomShape));
-//                 MESSAGE("Face with key " << key << " already in map");
-            }
+            key = FacesWithSizeMap.Add(TopoDS::Face(GeomShape) );
 
-            FaceId2ClassAttractor[key] = AtIt->second;
+            FaceId2ClassAttractor[key].push_back( AtIt->second );
+            ++theNbAttractors;
         }
         else{
           MESSAGE("Wrong shape type !!")
@@ -1880,6 +1881,8 @@ bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape)
   // Fix problem with locales
   Kernel_Utils::Localizer aLocalizer;
 
+  this->SMESH_Algo::_progress = 1e-3; // prevent progress advancment while computing attractors
+
   if ( !compute( aMesh, aShape, /*allowSubMeshClearing=*/true ))
     return false;
 
@@ -2163,11 +2166,17 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh&         aMesh,
       // -----------------
       // Class Attractors
       // -----------------
-      std::map<int,BLSURFPlugin_Attractor* >::iterator clAttractor_iter = FaceId2ClassAttractor.find(faceKey);
+      TId2ClsAttractorVec::iterator clAttractor_iter = FaceId2ClassAttractor.find(faceKey);
       if (clAttractor_iter != FaceId2ClassAttractor.end()){
         MESSAGE("Face indice: " << iface);
         MESSAGE("Adding attractor");
-        FaceIndex2ClassAttractor[iface]=clAttractor_iter->second;
+        std::vector< BLSURFPlugin_Attractor* > & attVec = clAttractor_iter->second;
+        for ( size_t i = 0; i < attVec.size(); ++i )
+          if ( !attVec[i]->IsMapBuilt() ) {
+            std::cout<<"Compute " << theNbAttractors-- << "-th attractor" <<std::endl;
+            attVec[i]->BuildMap();
+          }
+        FaceIndex2ClassAttractor[iface].swap( attVec );
         FaceId2ClassAttractor.erase(clAttractor_iter);
       }
     } // if (HasSizeMapOnFace && !use_precad)
@@ -3262,6 +3271,7 @@ status_t surf_fun(real *uv, real *xyz, real*du, real *dv,
 status_t size_on_surface(integer face_id, real *uv, real *size, void *user_data)
 {
   //MESSAGE("size_on_surface")
+  TId2ClsAttractorVec::iterator f2attVec;
   if (FaceId2PythonSmp.count(face_id) != 0){
     //MESSAGE("A size map is used to calculate size on face : "<<face_id)
     PyObject * pyresult = NULL;
@@ -3290,12 +3300,20 @@ status_t size_on_surface(integer face_id, real *uv, real *size, void *user_data)
     *size = result;
     PyGILState_Release(gstate);
   }
-  else if (FaceIndex2ClassAttractor.count(face_id) !=0 && !FaceIndex2ClassAttractor[face_id]->Empty()){
+  else if (( f2attVec = FaceIndex2ClassAttractor.find(face_id)) != FaceIndex2ClassAttractor.end() && !f2attVec->second.empty()){
 //    MESSAGE("attractor used on face :"<<face_id)
     // MESSAGE("List of attractor is not empty")
     // MESSAGE("Attractor empty : "<< FaceIndex2ClassAttractor[face_id]->Empty())
-    real result = FaceIndex2ClassAttractor[face_id]->GetSize(uv[0],uv[1]);
-    *size = result;
+    real result = 0;
+    //result = 1e100;
+    std::vector< BLSURFPlugin_Attractor* > & attVec = f2attVec->second;
+    for ( size_t i = 0; i < attVec.size(); ++i )
+    {
+      result += attVec[i]->GetSize(uv[0],uv[1]);
+      //result = Min( result, attVec[i]->GetSize(uv[0],uv[1]));
+    }
+    *size = result / attVec.size(); // mean of sizes defined by all attractors
+    //*size = result;
   }
   else {
     // MESSAGE("List of attractor is empty !!!")
index a9f54e563cac03ea994f0863ad07ebdc7d803a52..45600425748366978e922705ff0343831aacbf1d 100644 (file)
@@ -619,26 +619,26 @@ void BLSURFPlugin_Hypothesis::SetClassAttractorEntry(const std::string& entry, c
   
   const TopoDS_Shape AttractorShape = BLSURFPlugin_Hypothesis::entryToShape(attEntry);
   const TopoDS_Face FaceShape = TopoDS::Face(BLSURFPlugin_Hypothesis::entryToShape(entry));
-  bool attExists = (_classAttractors.find(entry) != _classAttractors.end());
-  double u1,u2,v1,v2, diag;
-  
-  if ( !attExists || (attExists && _classAttractors[entry]->GetAttractorEntry().compare(attEntry) != 0)){ 
-    ShapeAnalysis::GetFaceUVBounds(FaceShape,u1,u2,v1,v2);
-//     diag = sqrt((u2 - u1) * (u2 - u1) + (v2 - v1) * (v2 - v1));  
-    BLSURFPlugin_Attractor* myAttractor = new BLSURFPlugin_Attractor(FaceShape, AttractorShape, attEntry);//, 0.1 ); // test 0.002 * diag); 
-    myAttractor->BuildMap();
-    myAttractor->SetParameters(StartSize, EndSize, ActionRadius, ConstantRadius);
-    _classAttractors[entry] = myAttractor;
-    NotifySubMeshesHypothesisModification();
+  TAttractorMap::iterator attIt = _classAttractors.find(entry);
+  for ( ; attIt != _classAttractors.end(); ++attIt )
+    if ( attIt->first == entry && 
+         attIt->second->GetAttractorEntry() == attEntry )
+      break;
+  bool attExists = (attIt != _classAttractors.end());
+
+  BLSURFPlugin_Attractor* myAttractor;
+  if ( !attExists ) {
+    myAttractor = new BLSURFPlugin_Attractor(FaceShape, AttractorShape, attEntry);//, 0.1 );
+    _classAttractors.insert( make_pair( entry, myAttractor ));
   }
   else {
-    _classAttractors[entry]->SetParameters(StartSize, EndSize, ActionRadius, ConstantRadius);
-    if (!_classAttractors[entry]->IsMapBuilt()){
-      _classAttractors[entry]->BuildMap();
-    }
-    NotifySubMeshesHypothesisModification();
+    myAttractor = attIt->second;
   }
-    
+  // if (!myAttractor->IsMapBuilt())
+  //   myAttractor->BuildMap();
+  myAttractor->SetParameters(StartSize, EndSize, ActionRadius, ConstantRadius);
+
+  NotifySubMeshesHypothesisModification();
 }
 
 //=======================================================================
@@ -698,7 +698,11 @@ void BLSURFPlugin_Hypothesis::ClearEntry(const std::string& entry)
    else {
      TAttractorMap::iterator it_clAt = _classAttractors.find( entry );
      if ( it_clAt != _classAttractors.end() ) {
-       _classAttractors.erase(it_clAt);
+       do {
+         _classAttractors.erase(it_clAt);
+         it_clAt = _classAttractors.find( entry );
+       }
+       while ( it_clAt != _classAttractors.end() );
        MESSAGE("_classAttractors.size() = "<<_classAttractors.size())
        NotifySubMeshesHypothesisModification();
      }
@@ -2112,7 +2116,7 @@ std::istream & BLSURFPlugin_Hypothesis::LoadFrom(std::istream & load) {
   double attParams[4];
   double step;
   while (isOK && hasNewAttractor) {
-    std::cout<<"Load new attractor"<<std::endl;
+    //std::cout<<"Load new attractor"<<std::endl;
     isOK = (load >> newAtFaceEntry);
     if (isOK) {
       if (newAtFaceEntry == "__NEW_ATTRACTORS_END__")
@@ -2128,8 +2132,8 @@ std::istream & BLSURFPlugin_Hypothesis::LoadFrom(std::istream & load) {
       const TopoDS_Face faceShape = TopoDS::Face(BLSURFPlugin_Hypothesis::entryToShape(newAtFaceEntry));
       BLSURFPlugin_Attractor* attractor = new BLSURFPlugin_Attractor(faceShape, attractorShape, newAtShapeEntry);//, step);
       attractor->SetParameters(attParams[0], attParams[1], attParams[2], attParams[3]);
-      attractor->BuildMap();                     
-      _classAttractors[newAtFaceEntry]=attractor;
+      //attractor->BuildMap();                     
+      _classAttractors.insert( make_pair( newAtFaceEntry, attractor ));
     }
   }
   
index 6a0235033885a2e6fc29e39605be744990881f5f..6b2660b51520a94a9969a64789b7f3ec33a2d9f5 100644 (file)
@@ -167,7 +167,7 @@ public:
   const TSizeMap& GetCustomSizeMapEntries() const { return _customSizeMap; }
  */
   
-  typedef std::map< std::string, BLSURFPlugin_Attractor* > TAttractorMap;
+  typedef std::multimap< std::string, BLSURFPlugin_Attractor* > TAttractorMap;
   typedef std::map< std::string, std::vector<double> > TParamsMap; //TODO à finir 
   
   void SetClassAttractorEntry(const std::string& entry, const std::string& att_entry, double StartSize, double EndSize, double ActionRadius, double ConstantRadius);
index 91013ff309e42852a26aaccab80bf72bf78281d9..ba14abb30a76e4dc0f84adcd8fd5bf1a01d1db35 100644 (file)
@@ -1129,6 +1129,7 @@ QFrame* BLSURFPluginGUI_HypothesisCreator::buildFrame()
   connect( mySizeMapTable,      SIGNAL( itemClicked (QTreeWidgetItem *, int)),this,  SLOT( onSmpItemClicked(QTreeWidgetItem *, int) ) );
   connect( myGeomSelWdg2,       SIGNAL( contentModified() ),           this,         SLOT( onMapGeomContentModified() ) );
   connect( myGeomSelWdg1,       SIGNAL( contentModified() ),           this,         SLOT( onMapGeomContentModified() ) );
+  connect( myAttSelWdg,         SIGNAL( contentModified() ),           this,         SLOT( onMapGeomContentModified() ) );
 //   connect( myAttractorGroup,    SIGNAL( clicked(bool) ),               this,         SLOT( onAttractorGroupClicked(bool) ) );
   connect( mySizeMapTable,      SIGNAL( itemChanged (QTreeWidgetItem *, int)),this,  SLOT( onSetSizeMap(QTreeWidgetItem *, int) ) );
   connect( myAttractorCheck,    SIGNAL( stateChanged ( int )),         this,         SLOT( onAttractorClicked( int ) ) );
@@ -1882,28 +1883,31 @@ void BLSURFPluginGUI_HypothesisCreator::retrieveParams() const
     i.next();
     const QString entry = i.key();
     const QString sizeMap = i.value();
-    string shapeName = myGeomToolSelected->getNameFromEntry(entry.toStdString()); 
+    string shapeName = myGeomToolSelected->getNameFromEntry(entry.toStdString());
     int row = mySizeMapTable->topLevelItemCount();
     QTreeWidgetItem* item = new QTreeWidgetItem();
-    mySizeMapTable->addTopLevelItem( item ); 
+    mySizeMapTable->addTopLevelItem( item );
     item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled );
     item->setData(SMP_ENTRY_COLUMN,Qt::DisplayRole, QVariant(entry) );
     item->setData(SMP_NAME_COLUMN, Qt::DisplayRole, QVariant( QString::fromStdString(shapeName) ) );
-    if (that->myATTMap.contains(entry)){
-      const QString attEntry = that->myATTMap[entry];
-      std::string attName = myGeomToolSelected->getNameFromEntry(attEntry.toStdString());
-      QTreeWidgetItem* child = new QTreeWidgetItem();
-      item->addChild( child );
-      item->setExpanded(true);
-      child->setData(SMP_SIZEMAP_COLUMN, Qt::EditRole, QVariant( sizeMap  ) );
-      child->setData(SMP_ENTRY_COLUMN, Qt::DisplayRole, QVariant( attEntry  ) );
-      child->setData(SMP_NAME_COLUMN, Qt::DisplayRole, QVariant( QString::fromStdString( attName ) ) );
-   
-      if (that->myAttDistMap[entry] >  std::numeric_limits<double>::epsilon()){
-        item->setData(SMP_SIZEMAP_COLUMN, Qt::DisplayRole, QVariant( QString::fromStdString("Attractor" )  ) ); 
-      }
-      else{
-        item->setData(SMP_SIZEMAP_COLUMN, Qt::DisplayRole, QVariant( QString::fromStdString("Constant Size" )  ) );
+    if (that->myATTMap.contains(entry)) {
+      TAttractorVec & attVec = that->myATTMap[entry];
+      for ( size_t i = 0; i < attVec.size(); ++i )
+      {
+        std::string attName = myGeomToolSelected->getNameFromEntry( attVec[i].attEntry );
+        QTreeWidgetItem* child = new QTreeWidgetItem();
+        item->addChild( child );
+        item->setExpanded(true);
+        child->setData(SMP_SIZEMAP_COLUMN, Qt::EditRole, QVariant( attVec[i].startSize  ));
+        child->setData(SMP_ENTRY_COLUMN, Qt::DisplayRole, QVariant( attVec[i].attEntry.c_str() ));
+        child->setData(SMP_NAME_COLUMN, Qt::DisplayRole, QVariant( attName.c_str() ));
+
+        if ( attVec[i].infDist >  std::numeric_limits<double>::epsilon()){
+          item->setData(SMP_SIZEMAP_COLUMN, Qt::DisplayRole, QVariant( "Attractor" ));
+        }
+        else{
+          item->setData(SMP_SIZEMAP_COLUMN, Qt::DisplayRole, QVariant( "Constant Size" ));
+        }
       }
     }
     else
@@ -2047,8 +2051,8 @@ bool BLSURFPluginGUI_HypothesisCreator::readParamsFromHypo( BlsurfHypothesisData
 
   that->mySMPMap.clear();
   that->myATTMap.clear();
-  that->myAttDistMap.clear();
-  that->myDistMap.clear();
+  // that->myAttDistMap.clear();
+  // that->myDistMap.clear();
 
   // classic size maps
   BLSURFPlugin::string_array_var mySizeMaps = h->GetSizeMapEntries();
@@ -2117,15 +2121,12 @@ bool BLSURFPluginGUI_HypothesisCreator::readParamsFromHypo( BlsurfHypothesisData
     QString faceEntry = myAttractorParams.faceEntry.in();
     QString attEntry  = myAttractorParams.attEntry.in();
     MESSAGE("attEntry = "<<attEntry.toStdString())
-    double  startSize = myAttractorParams.startSize;
-    double  endSize   = myAttractorParams.endSize;
-    double  infDist   = myAttractorParams.infDist;
-    double  constDist = myAttractorParams.constDist;
-    that->mySMPMap[faceEntry] = QString::number( startSize, 'g',  6 ); // TODO utiliser les préférences ici (cf. sketcher)
+    that->mySMPMap[faceEntry] = QString::number( myAttractorParams.startSize, 'g',  6 ); // TODO utiliser les préférences ici (cf. sketcher)
     that->mySMPShapeTypeMap[faceEntry] = myGeomToolSelected->entryToShapeType(faceEntry.toStdString());
-    that->myATTMap[faceEntry] = attEntry;
-    that->myAttDistMap[faceEntry] = infDist;
-    that->myDistMap[faceEntry] = constDist;
+    that->myATTMap[faceEntry].push_back( TAttractor( myAttractorParams.attEntry.in(),
+                                                     myAttractorParams.startSize,
+                                                     myAttractorParams.infDist,
+                                                     myAttractorParams.constDist ));
   }
   
   // Enforced vertices
@@ -2337,14 +2338,17 @@ bool BLSURFPluginGUI_HypothesisCreator::storeParamsToHypo( const BlsurfHypothesi
 //        h->SetCustomSizeMapEntry( entry.toLatin1().constData(), sizeMap.toLatin1().constData() );
       }
       else {
-        if (!myATTMap[entry].isEmpty()){
-          QString att_entry = myATTMap[entry];
-          double infDist = myAttDistMap[entry];
-          double constDist = myDistMap[entry];
-          double phySize = h->GetPhySize();
-          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
-          h->SetClassAttractorEntry( entry.toLatin1().constData(), att_entry.toLatin1().constData(), sizeMap.toDouble() , phySize, infDist, constDist ); 
-          QApplication::restoreOverrideCursor();
+        if (!myATTMap[entry].empty()){
+          const TAttractorVec& attVec = myATTMap[entry];
+          for ( size_t i = 0; i < attVec.size(); ++i )
+          {
+            h->SetClassAttractorEntry( entry.toLatin1().constData(),
+                                       attVec[i].attEntry.c_str(),
+                                       attVec[i].startSize,
+                                       h->GetPhySize(),
+                                       attVec[i].infDist,
+                                       attVec[i].constDist );
+          }
         }
         else {
           QString fullSizeMap;
@@ -2747,75 +2751,108 @@ void BLSURFPluginGUI_HypothesisCreator::onDeleteOption()
 
 void BLSURFPluginGUI_HypothesisCreator::onMapGeomContentModified()
 {
-  BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
-  
-  if ( myGeomSelWdg2->IsObjectSelected() ){ 
+  if ( myGeomSelWdg2->IsObjectSelected() ){
     mySMapObject = myGeomSelWdg2->GetObject< GEOM::GEOM_Object >(0);
   }
   else if ( myGeomSelWdg1->IsObjectSelected() ){
     mySMapObject = myGeomSelWdg1->GetObject< GEOM::GEOM_Object >(0);
   }
-  std::string entry = (string) mySMapObject->GetStudyEntry();
-  QString qEntry = QString::fromStdString(entry);
-  if (that->mySMPMap.contains(qEntry) && that->mySMPMap[qEntry] != "__TO_DELETE__" ) {  
-    addMapButton->setEnabled(false);
-    modifyMapButton->setEnabled(true);
-  }
-  else{
-    addMapButton->setEnabled(true);
-    modifyMapButton->setEnabled(false);
+  else {
+    mySMapObject = GEOM::GEOM_Object::_nil();
+  }
+  bool dataAvailable = !mySMapObject->_is_nil();
+  QString qEntry;
+  if ( dataAvailable )
+    qEntry = SMESH::toQStr( mySMapObject->GetStudyEntry() );
+
+  bool mapExists = ( mySMPMap.contains(qEntry) && mySMPMap[qEntry] != "__TO_DELETE__" );
+  if (( mapExists && myGeomSelWdg2->IsObjectSelected() )  &&
+      ( dataAvailable = myAttSelWdg->isEnabled() )        &&
+      ( dataAvailable = myAttSelWdg->IsObjectSelected() ) &&
+      ( myATTMap.contains( qEntry )))
+  {
+    mapExists = false;
+    QString attEntry = myAttSelWdg->GetValue();
+    const TAttractorVec& attVec = myATTMap[ qEntry ];
+    for ( size_t i = 0; i < attVec.size() && !mapExists; ++i )
+      mapExists = ( attEntry == attVec[i].attEntry.c_str() );
   }
-      
-} 
+
+  addMapButton->setEnabled( !mapExists && dataAvailable );
+  modifyMapButton->setEnabled( mapExists && dataAvailable );
+}
 
 void BLSURFPluginGUI_HypothesisCreator::onSmpItemClicked(QTreeWidgetItem * item, int col)
 { 
   MESSAGE("BLSURFPluginGUI_HypothesisCreator::onSmpItemClicked("<<col<<")")
   BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
-  if (col == SMP_SIZEMAP_COLUMN){
+  if (col == SMP_SIZEMAP_COLUMN) {
     QString entry   = item->data( SMP_ENTRY_COLUMN, Qt::EditRole ).toString();
+    QString childEntry;
     if (!mySMPMap.contains(entry))
-      return;
+    {
+      if ( QTreeWidgetItem* parent = item->parent() )
+      {
+        childEntry = entry;
+        item = parent;
+        entry = item->data( SMP_ENTRY_COLUMN, Qt::EditRole ).toString();
+      }
+      if (!mySMPMap.contains(entry))
+        return;
+    }
     QString sizeMap = item->data( SMP_SIZEMAP_COLUMN, Qt::EditRole ).toString();
-    CORBA::Object_var obj = entryToObject(entry); 
-    if (sizeMap.startsWith("Attractor") || sizeMap.startsWith("Constant")){  // ADVANCED MAPS
+    CORBA::Object_var obj = entryToObject(entry);
+    if (sizeMap.startsWith("Attractor") || sizeMap.startsWith("Constant")) {  // ADVANCED MAPS
       smpTab->setCurrentIndex(ATT_TAB);         // Change Tab
-      double phySize = that->mySMPMap[entry].toDouble();  // Retrieve values of the selected item in the current tab widgets
-      double infDist = that->myAttDistMap[entry];
-      double constDist = that->myDistMap[entry];
-      QString attEntry = that->myATTMap[entry];
-      CORBA::Object_var attObj = entryToObject(attEntry);
-      myAttSizeSpin->setValue(phySize);
-      if (sizeMap.startsWith("Attractor")){     
-        myAttDistSpin->setValue(infDist);
-        myAttractorCheck->setChecked(true);
-      }
-      else {
-        myAttractorCheck->setChecked(false);
-      }
-      if (sizeMap.startsWith("Constant") || constDist > std::numeric_limits<double>::epsilon()){
-        myAttDistSpin2->setValue(constDist);
-        myConstSizeCheck->setChecked(true);
-      }
-      else{
-        myConstSizeCheck->setChecked(false);
+      // Retrieve values of the selected item in the current tab widgets
+      const TAttractorVec& attVec = myATTMap[entry];
+      if ( !attVec.empty() )
+      {
+        int iAtt = 0;
+        if ( !childEntry.isEmpty() )
+          for ( size_t i = 0; i < attVec.size(); ++i )
+            if ( childEntry == attVec[i].attEntry.c_str() )
+            {
+              iAtt = i;
+              break;
+            }
+        double phySize   = attVec[iAtt].startSize;
+        double infDist   = attVec[iAtt].infDist;
+        double constDist = attVec[iAtt].constDist;
+        QString attEntry = attVec[iAtt].attEntry.c_str();
+        CORBA::Object_var attObj = entryToObject(attEntry);
+        myAttSizeSpin->setValue(phySize);
+        if ( infDist > std::numeric_limits<double>::epsilon() /*sizeMap.startsWith("Attractor")*/){
+          myAttDistSpin->setValue(infDist);
+          myAttractorCheck->setChecked(true);
+        }
+        else {
+          myAttractorCheck->setChecked(false);
+        }
+        if (/*sizeMap.startsWith("Constant") || */constDist > std::numeric_limits<double>::epsilon()){
+          myAttDistSpin2->setValue(constDist);
+          myConstSizeCheck->setChecked(true);
+        }
+        else{
+          myConstSizeCheck->setChecked(false);
+        }
+        myGeomSelWdg2->SetObject(obj);
+        myAttSelWdg->SetObject(attObj);
       }
-      myGeomSelWdg2->SetObject(obj); 
-      myAttSelWdg->SetObject(attObj);
     }
     else {                                                                   // CLASSIC MAPS
       smpTab->setCurrentIndex(SMP_STD_TAB);  // Change Tab
       myGeomSelWdg1->SetObject(obj);         // Retrieve values of the selected item in the current tab widgets
       if (!sizeMap.startsWith("def")){
-        mySmpSizeSpin->setValue(that->mySMPMap[entry].toDouble()); 
+        mySmpSizeSpin->setValue(that->mySMPMap[entry].toDouble());
       }
-    }  
-  } 
+    }
+  }
 }
 
 void BLSURFPluginGUI_HypothesisCreator::onTabChanged(int tab)
 {
-  getGeomSelectionTool()->selectionMgr()->clearFilters();// rm other tab filters
+  getGeomSelectionTool()->selectionMgr()->clearFilters();
   if ( sender() == myTabWidget )
   {
     myGeomSelWdg1             ->deactivateSelection();
@@ -2876,7 +2913,8 @@ void BLSURFPluginGUI_HypothesisCreator::onAttractorClicked(int state)
     else if (!myAttSelWdg->IsObjectSelected()){           // Only constant size selected
       myAttSelWdg->SetDefaultText(tr("BLS_SEL_SHAPE"), "QLineEdit { color: grey }");
     }
-  }   
+  }
+  onMapGeomContentModified();
 }
 
 void BLSURFPluginGUI_HypothesisCreator::onConstSizeClicked(int state)
@@ -2907,6 +2945,7 @@ void BLSURFPluginGUI_HypothesisCreator::onConstSizeClicked(int state)
     myAttSelWdg->SetDefaultText(tr("BLS_SEL_ATTRACTOR"), "QLineEdit { color: grey }");
     }
   }   
+  onMapGeomContentModified();
 }
 
 void BLSURFPluginGUI_HypothesisCreator::onRemoveMap()
@@ -2929,10 +2968,10 @@ void BLSURFPluginGUI_HypothesisCreator::onRemoveMap()
         that->mySMPShapeTypeMap.remove(entry);
       if (that->myATTMap.contains(entry))
         that->myATTMap.remove(entry);
-      if (that->myDistMap.contains(entry))
-        that->myDistMap.remove(entry);
-      if (that->myAttDistMap.contains(entry))
-        that->myAttDistMap.remove(entry);
+      // if (that->myDistMap.contains(entry))
+      //   that->myDistMap.remove(entry);
+      // if (that->myAttDistMap.contains(entry))
+      //   that->myAttDistMap.remove(entry);
       delete item;
   }
   mySizeMapTable->resizeColumnToContents(SMP_NAME_COLUMN);
@@ -2972,8 +3011,8 @@ void BLSURFPluginGUI_HypothesisCreator::onSetSizeMap(QTreeWidgetItem* item, int
 void BLSURFPluginGUI_HypothesisCreator::onAddMap()
 {
   bool res = false;
-  if ( smpTab->currentIndex() == ATT_TAB ){    
-    if ( myGeomSelWdg2->IsObjectSelected() && myAttSelWdg->IsObjectSelected() ){ 
+  if ( smpTab->currentIndex() == ATT_TAB ){
+    if ( myGeomSelWdg2->IsObjectSelected() && myAttSelWdg->IsObjectSelected() ){
       mySMapObject = myGeomSelWdg2->GetObject< GEOM::GEOM_Object >(0);
       myAttObject = myAttSelWdg->GetObject< GEOM::GEOM_Object >(0);
       res = insertAttractor(mySMapObject, myAttObject);
@@ -2982,8 +3021,8 @@ void BLSURFPluginGUI_HypothesisCreator::onAddMap()
   if (smpTab->currentIndex() == SMP_STD_TAB  ){
     if ( myGeomSelWdg1->IsObjectSelected() ){
       mySMapObject = myGeomSelWdg1->GetObject< GEOM::GEOM_Object >(0);
-      res = insertElement(mySMapObject);  
-    }  
+      res = insertElement(mySMapObject);
+    }
   }
   if ( !res ) {
     // Local size should be more than 0
@@ -3047,8 +3086,8 @@ void BLSURFPluginGUI_HypothesisCreator::onModifyMap()
 bool BLSURFPluginGUI_HypothesisCreator::insertElement(GEOM::GEOM_Object_var anObject, bool modify)
 {
   MESSAGE("BLSURFPluginGUI_HypothesisCreator::insertElement()");
-  BLSURFPlugin::BLSURFPlugin_Hypothesis_var h =
-    BLSURFPlugin::BLSURFPlugin_Hypothesis::_narrow( initParamsHypothesis());
+  // BLSURFPlugin::BLSURFPlugin_Hypothesis_var h =
+  //   BLSURFPlugin::BLSURFPlugin_Hypothesis::_narrow( initParamsHypothesis());
 
   BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
 
@@ -3100,7 +3139,7 @@ bool BLSURFPluginGUI_HypothesisCreator::insertElement(GEOM::GEOM_Object_var anOb
     mySizeMapTable->addTopLevelItem(item);
   }
   that->mySMPMap[shapeEntry] = sizeMap;
-  that->myDistMap[shapeEntry] = 0. ;
+  //that->myDistMap[shapeEntry] = 0. ;
   that->mySMPShapeTypeMap[shapeEntry] = shapeType;
   item->setFlags( Qt::ItemIsSelectable |Qt::ItemIsEditable   |Qt::ItemIsEnabled );
   item->setData(SMP_ENTRY_COLUMN, Qt::EditRole, QVariant(shapeEntry) );
@@ -3162,29 +3201,39 @@ bool BLSURFPluginGUI_HypothesisCreator::insertAttractor(GEOM::GEOM_Object_var aF
   QString constDistString = QString::fromStdString(oss3.str());
   
   QTreeWidgetItem* item; 
-  QTreeWidgetItem* child; 
-  if (modify){
+  QTreeWidgetItem* child;
+  TAttractor attParams( attEntry.c_str(), phySize, infDist, constDist );
+  if (modify) {
     int rowToChange = findRowFromEntry(shapeEntry);
     item = mySizeMapTable->topLevelItem( rowToChange );
-    child = item->child( 0 );
+    
+    for ( int i = 0, nb = item->childCount(); i < nb; ++i )
+      if (( child = item->child( i )))
+        if ( qAttEntry == child->data( SMP_ENTRY_COLUMN, Qt::EditRole ).toString() )
+          break;
+    TAttractorVec & attVec = myATTMap[shapeEntry];
+    for ( size_t i = 0; i < attVec.size(); ++i )
+      if ( attVec[i].attEntry == attEntry )
+      {
+        attVec[i] = attParams;
+        break;
+      }
   }
   else{
-    if (that->mySMPMap.contains(shapeEntry)) {  
-      if (that->mySMPMap[shapeEntry] != "__TO_DELETE__") {
-    //             MESSAGE("Size map for shape with name(entry): "<< shapeName << "(" << entry << ")");
-        return false;
-      }
-    }
+    // if (that->mySMPMap.contains(shapeEntry)) {  
+    //   if (that->mySMPMap[shapeEntry] != "__TO_DELETE__") {
+    // //             MESSAGE("Size map for shape with name(entry): "<< shapeName << "(" << entry << ")");
+    //     return false;
+    //   }
+    // }
     item = new QTreeWidgetItem();
     child = new QTreeWidgetItem();
     mySizeMapTable->addTopLevelItem(item);
     item->addChild(child);
+    myATTMap[shapeEntry].push_back( attParams );
   }
-  that->mySMPMap.insert(shapeEntry,sizeMap);
-  that->myATTMap.insert(shapeEntry,qAttEntry);
-  that->myAttDistMap.insert(shapeEntry,infDist);
-  that->myDistMap.insert(shapeEntry,constDist);
-  that->mySMPShapeTypeMap.insert(shapeEntry,shapeType);
+  mySMPMap.insert(shapeEntry,sizeMap);
+  mySMPShapeTypeMap.insert(shapeEntry,shapeType);
   item->setExpanded(true); 
   item->setData(SMP_ENTRY_COLUMN, Qt::EditRole, QVariant(shapeEntry) );
   item->setData(SMP_NAME_COLUMN, Qt::EditRole, QVariant(QString::fromStdString(faceName)) );
index e936a56cbc896cfdfa1d65c310e233c8c4b9fab5..cfeb7c623e96e7ead8e4ad0c05a86b40586ce1d3 100644 (file)
@@ -114,7 +114,20 @@ struct TEnfVertex{
   TEnfVertexCoords coords;
   TEnfName grpName;
 };
-
+// Attractor
+struct TAttractor{
+  std::string attEntry;
+  double      startSize;
+  double      infDist;
+  double      constDist;
+  TAttractor( const char* theAttEntry, double theStartSize, double theInfDist, double theConstDist)
+    : attEntry( theAttEntry ),
+      startSize( theStartSize ),
+      infDist( theInfDist ),
+      constDist( theConstDist )
+  {}
+};
+typedef std::vector< TAttractor > TAttractorVec;
 
 struct CompareEnfVertices
 {
@@ -312,9 +325,9 @@ private:
 
   // map =  entry , size map
   QMap<QString, QString>          mySMPMap;           // Map <face entry, size>
-  QMap<QString, QString>          myATTMap;           // Map <face entry, att. entry>
-  QMap<QString, double>           myDistMap;          // Map <entry,distance with constant size> 
-  QMap<QString, double>           myAttDistMap;       // Map <entry, influence distance> 
+  QMap<QString, TAttractorVec >   myATTMap;           // Map <face entry, att. entry, etc>
+  // QMap<QString, double>           myDistMap;          // Map <entry,distance with constant size> 
+  // QMap<QString, double>           myAttDistMap;       // Map <entry, influence distance> 
   QMap<QString, TopAbs_ShapeEnum> mySMPShapeTypeMap;
   GeomSelectionTools*             GeomToolSelected;
   LightApp_SelectionMgr*          aSel;