Salome HOME
merge from branch V5_1_sizemap tag mergeto_V5_1_main_8oct09
authornge <nge>
Thu, 8 Oct 2009 10:18:52 +0000 (10:18 +0000)
committernge <nge>
Thu, 8 Oct 2009 10:18:52 +0000 (10:18 +0000)
13 files changed:
idl/BLSURFPlugin_Algorithm.idl
src/BLSURFPlugin/BLSURFPlugin_BLSURF.cxx
src/BLSURFPlugin/BLSURFPlugin_BLSURF.hxx
src/BLSURFPlugin/BLSURFPlugin_Hypothesis.cxx
src/BLSURFPlugin/BLSURFPlugin_Hypothesis.hxx
src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.cxx
src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.hxx
src/BLSURFPlugin/Makefile.am
src/GUI/BLSURFPluginGUI_HypothesisCreator.cxx
src/GUI/BLSURFPluginGUI_HypothesisCreator.h
src/GUI/BLSURFPlugin_msg_en.ts
src/PluginUtils/GeomSelectionTools.cxx
src/PluginUtils/GeomSelectionTools.h

index 470dffc043133e0823040c996b9048207280a42a..939c739fab95260b89d533c68190183ec388c635 100644 (file)
 module BLSURFPlugin
 {
   typedef sequence<string> string_array;
-
+  typedef sequence<double,3> TEnforcedVertex;
+  typedef sequence<TEnforcedVertex> TEnforcedVertexList;
+  struct TEnforcedVertexMapElement {
+    string entry;
+    TEnforcedVertexList vertexList;
+  };
+  typedef sequence<TEnforcedVertexMapElement> TEnforcedVertexMap;
+  
   /*!
    * BLSURFPlugin_BLSURF: interface of BLSURF algorithm
    */
@@ -172,7 +179,7 @@ module BLSURFPlugin
     void UnsetEntry(in string entry);
 
     /*!
-     * Set a SizeMap on geom object
+     * Set/unset a SizeMap on geom object
      */
     void         SetSizeMap(in GEOM::GEOM_Object GeomObj, in string sizeMap);
     void         UnsetSizeMap(in GEOM::GEOM_Object GeomObj);
@@ -185,7 +192,7 @@ module BLSURFPlugin
     string_array GetSizeMapEntries();
 
     /*!
-     * Set an attractor on geom object
+     * Set/unset an attractor on geom object
      */
     void         SetAttractor(in GEOM::GEOM_Object GeomObj, in string attractor);
     void         UnsetAttractor(in GEOM::GEOM_Object GeomObj);
@@ -204,6 +211,39 @@ module BLSURFPlugin
     void         UnsetCustomSizeMap(in GEOM::GEOM_Object GeomObj);
     string_array GetCustomSizeMapEntries();
 */
+    ///////////////////////
+    // ENFORCED VERTEXES //
+    ///////////////////////
+    
+    TEnforcedVertexMap GetAllEnforcedVertices();
+    void               ClearAllEnforcedVertices();
+    
+    /*!
+     * Set/get/unset an enforced vertex on geom object
+     */
+    void         SetEnforcedVertex(in GEOM::GEOM_Object GeomObj, in double x, in double y, in double z) raises (SALOME::SALOME_Exception);
+//     void         SetEnforcedVertexList(in GEOM::GEOM_Object GeomObj, in TEnforcedVertexList vertexList) raises (SALOME::SALOME_Exception);
+    
+    TEnforcedVertexList GetEnforcedVertices(in GEOM::GEOM_Object GeomObj) raises (SALOME::SALOME_Exception);
+    
+    void         UnsetEnforcedVertex(in GEOM::GEOM_Object GeomObj, in double x, in double y, in double z) raises (SALOME::SALOME_Exception);
+//     void         UnsetEnforcedVertexList(in GEOM::GEOM_Object GeomObj, in TEnforcedVertexList vertexList) raises (SALOME::SALOME_Exception);
+    void         UnsetEnforcedVertices(in GEOM::GEOM_Object GeomObj) raises (SALOME::SALOME_Exception);
+    
+   /*!
+    * Set/get/unset an enforced vertex on geom object given by entry
+    */
+    void         SetEnforcedVertexEntry(in string entry, in double x, in double y, in double z) raises (SALOME::SALOME_Exception);
+//     void         SetEnforcedVertexListEntry(in string entry, in TEnforcedVertexList vertexList) raises (SALOME::SALOME_Exception);
+//     
+    TEnforcedVertexList GetEnforcedVerticesEntry(in string entry) raises (SALOME::SALOME_Exception);
+//     
+    void         UnsetEnforcedVertexEntry(in string entry, in double x, in double y, in double z) raises (SALOME::SALOME_Exception);
+//     void         UnsetEnforcedVertexListEntry(in string entry, in TEnforcedVertexList vertexList) raises (SALOME::SALOME_Exception);
+    void         UnsetEnforcedVerticesEntry(in string entry) raises (SALOME::SALOME_Exception);
+    
+    ///////////////////////
+
   };
 };
 
index 41d01a83bf7e0a8a2ad12c92469990c8d109377b..3f520634d1b44f0a3d16f7ea906e1336cc68ac2f 100644 (file)
@@ -43,6 +43,7 @@ extern "C"{
 #include <limits>
 #include <list>
 #include <vector>
+#include <set>
 #include <cstdlib>
 
 #include <BRep_Tool.hxx>
@@ -51,6 +52,11 @@ extern "C"{
 #include <NCollection_Map.hxx>
 #include <Standard_ErrorHandler.hxx>
 
+extern "C"{
+#include "distene/blsurf.h"
+#include <distene/api.h>
+}
+
 #include <Geom_Surface.hxx>
 #include <Handle_Geom_Surface.hxx>
 #include <Geom2d_Curve.hxx>
@@ -72,6 +78,8 @@ extern "C"{
 #include <GeomAPI_ProjectPointOnSurf.hxx>
 #include <gp_XY.hxx>
 #include <gp_XYZ.hxx>
+// #include <BRepClass_FaceClassifier.hxx>
+#include <TopTools_MapOfShape.hxx>
 
 /* ==================================
  * ===========  PYTHON ==============
@@ -120,48 +128,48 @@ static PyTypeObject PyStdOut_Type = {
   /* The ob_type field must be initialized in the module init function
    * to be portable to Windows without using C++. */
   PyObject_HEAD_INIT(NULL)
-  0,      /*ob_size*/
-  "PyOut",   /*tp_name*/
-  sizeof(PyStdOut),  /*tp_basicsize*/
-  0,      /*tp_itemsize*/
+  0,                            /*ob_size*/
+  "PyOut",                      /*tp_name*/
+  sizeof(PyStdOut),             /*tp_basicsize*/
+  0,                            /*tp_itemsize*/
   /* methods */
   (destructor)PyStdOut_dealloc, /*tp_dealloc*/
-  0,      /*tp_print*/
-  0, /*tp_getattr*/
-  0, /*tp_setattr*/
-  0,      /*tp_compare*/
-  0,      /*tp_repr*/
-  0,      /*tp_as_number*/
-  0,      /*tp_as_sequence*/
-  0,      /*tp_as_mapping*/
-  0,      /*tp_hash*/
-        0,                      /*tp_call*/
-        0,                      /*tp_str*/
-        PyObject_GenericGetAttr,                      /*tp_getattro*/
-        /* softspace is writable:  we must supply tp_setattro */
-        PyObject_GenericSetAttr,    /* tp_setattro */
-        0,                      /*tp_as_buffer*/
-        Py_TPFLAGS_DEFAULT,     /*tp_flags*/
-        0,                      /*tp_doc*/
-        0,                      /*tp_traverse*/
-        0,                      /*tp_clear*/
-        0,                      /*tp_richcompare*/
-        0,                      /*tp_weaklistoffset*/
-        0,                      /*tp_iter*/
-        0,                      /*tp_iternext*/
-        PyStdOut_methods,                      /*tp_methods*/
-        PyStdOut_memberlist,                      /*tp_members*/
-        0,                      /*tp_getset*/
-        0,                      /*tp_base*/
-        0,                      /*tp_dict*/
-        0,                      /*tp_descr_get*/
-        0,                      /*tp_descr_set*/
-        0,                      /*tp_dictoffset*/
-        0,                      /*tp_init*/
-        0,                      /*tp_alloc*/
-        0,                      /*tp_new*/
-        0,                      /*tp_free*/
-        0,                      /*tp_is_gc*/
+  0,                            /*tp_print*/
+  0,                            /*tp_getattr*/
+  0,                            /*tp_setattr*/
+  0,                            /*tp_compare*/
+  0,                            /*tp_repr*/
+  0,                            /*tp_as_number*/
+  0,                            /*tp_as_sequence*/
+  0,                            /*tp_as_mapping*/
+  0,                            /*tp_hash*/
+  0,                            /*tp_call*/
+  0,                            /*tp_str*/
+  PyObject_GenericGetAttr,      /*tp_getattro*/
+  /* softspace is writable:  we must supply tp_setattro */
+  PyObject_GenericSetAttr,      /* tp_setattro */
+  0,                            /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT,           /*tp_flags*/
+  0,                            /*tp_doc*/
+  0,                            /*tp_traverse*/
+  0,                            /*tp_clear*/
+  0,                            /*tp_richcompare*/
+  0,                            /*tp_weaklistoffset*/
+  0,                            /*tp_iter*/
+  0,                            /*tp_iternext*/
+  PyStdOut_methods,             /*tp_methods*/
+  PyStdOut_memberlist,          /*tp_members*/
+  0,                            /*tp_getset*/
+  0,                            /*tp_base*/
+  0,                            /*tp_dict*/
+  0,                            /*tp_descr_get*/
+  0,                            /*tp_descr_set*/
+  0,                            /*tp_dictoffset*/
+  0,                            /*tp_init*/
+  0,                            /*tp_alloc*/
+  0,                            /*tp_new*/
+  0,                            /*tp_free*/
+  0,                            /*tp_is_gc*/
 };
 
 PyObject * newPyStdOut( std::string& out )
@@ -179,13 +187,21 @@ PyObject * newPyStdOut( std::string& out )
 ////////////////////////END PYTHON///////////////////////////
 
 //////////////////MY MAPS////////////////////////////////////////
+TopTools_IndexedMapOfShape FacesWithSizeMap;
 std::map<int,string> FaceId2SizeMap;
+TopTools_IndexedMapOfShape EdgesWithSizeMap;
 std::map<int,string> EdgeId2SizeMap;
+TopTools_IndexedMapOfShape VerticesWithSizeMap;
 std::map<int,string> VertexId2SizeMap;
+
 std::map<int,PyObject*> FaceId2PythonSmp;
 std::map<int,PyObject*> EdgeId2PythonSmp;
 std::map<int,PyObject*> VertexId2PythonSmp;
 
+std::map<int,std::vector<double> > FaceId2AttractorCoords;
+
+TopTools_IndexedMapOfShape FacesWithEnforcedVertices;
+std::map< int, std::set< std::vector<double> > > FaceId2EnforcedVertexCoords;
 
 bool HasSizeMapOnFace=false;
 bool HasSizeMapOnEdge=false;
@@ -234,12 +250,19 @@ BLSURFPlugin_BLSURF::BLSURFPlugin_BLSURF(int hypId, int studyId,
   PyRun_SimpleString("from math import *");
   PyGILState_Release(gstate);
 
+  FacesWithSizeMap.Clear();
   FaceId2SizeMap.clear();
+  EdgesWithSizeMap.Clear();
   EdgeId2SizeMap.clear();
+  VerticesWithSizeMap.Clear();
   VertexId2SizeMap.clear();
   FaceId2PythonSmp.clear();
   EdgeId2PythonSmp.clear();
   VertexId2PythonSmp.clear();
+  FaceId2AttractorCoords.clear();
+  FacesWithEnforcedVertices.Clear();
+  FaceId2EnforcedVertexCoords.clear();
+
 }
 
 //=============================================================================
@@ -327,9 +350,14 @@ status_t size_on_vertex(integer vertex_id, real *size, void *user_data);
 
 double my_u_min=1e6,my_v_min=1e6,my_u_max=-1e6,my_v_max=-1e6;
 
+typedef struct {
+       gp_XY uv;
+       gp_XYZ xyz;
+} projectionPoint;
 /////////////////////////////////////////////////////////
-gp_XY getUV(const TopoDS_Face& face, const gp_XYZ& point)
+projectionPoint getProjectionPoint(const TopoDS_Face& face, const gp_XYZ& point)
 {
+  projectionPoint myPoint;
   Handle(Geom_Surface) surface = BRep_Tool::Surface(face);
   GeomAPI_ProjectPointOnSurf projector( point, surface );
   if ( !projector.IsDone() || projector.NbPoints()==0 )
@@ -337,7 +365,11 @@ gp_XY getUV(const TopoDS_Face& face, const gp_XYZ& point)
 
   Quantity_Parameter u,v;
   projector.LowerDistanceParameters(u,v);
-  return gp_XY(u,v);
+  myPoint.uv = gp_XY(u,v);
+  gp_Pnt aPnt = projector.NearestPoint();
+  myPoint.xyz = gp_XYZ(aPnt.X(),aPnt.Y(),aPnt.Z());
+  //return gp_XY(u,v);
+  return myPoint;
 }
 /////////////////////////////////////////////////////////
 
@@ -384,6 +416,186 @@ TopoDS_Shape BLSURFPlugin_BLSURF::entryToShape(std::string entry)
     }
     return S;
 }
+
+/////////////////////////////////////////////////////////
+TopoDS_Shape BLSURFPlugin_BLSURF::entryToShape(std::string entry)
+{
+  MESSAGE("BLSURFPlugin_BLSURF::entryToShape"<<entry );
+  GEOM::GEOM_Object_var aGeomObj;
+  TopoDS_Shape S = TopoDS_Shape();
+  SALOMEDS::SObject_var aSObj = myStudy->FindObjectID( entry.c_str() );
+  SALOMEDS::GenericAttribute_var anAttr;
+
+  if (!aSObj->_is_nil() && aSObj->FindAttribute(anAttr, "AttributeIOR")) {
+    SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
+    CORBA::String_var aVal = anIOR->Value();
+    CORBA::Object_var obj = myStudy->ConvertIORToObject(aVal);
+    aGeomObj = GEOM::GEOM_Object::_narrow(obj);
+  }
+  if ( !aGeomObj->_is_nil() )
+    S = smeshGen_i->GeomObjectToShape( aGeomObj.in() );
+  return S;
+}
+
+/////////////////////////////////////////////////////////
+void createEnforcedVertexOnFace(TopoDS_Shape GeomShape, BLSURFPlugin_Hypothesis::TEnforcedVertexList enforcedVertexList)
+{
+  double xe, ye, ze;
+  std::vector<double> coords;
+  BLSURFPlugin_Hypothesis::TEnforcedVertex enforcedVertex;
+  BLSURFPlugin_Hypothesis::TEnforcedVertexList::const_iterator evlIt = enforcedVertexList.begin();
+
+  for( ; evlIt != enforcedVertexList.end() ; ++evlIt ) {
+    coords.clear();
+    enforcedVertex = *evlIt;
+    xe = enforcedVertex[0];
+    ye = enforcedVertex[1];
+    ze = enforcedVertex[2];
+    MESSAGE("Enforced Vertex: " << xe << ", " << ye << ", " << ze);
+    // Get the (u,v) values of the enforced vertex on the face
+    projectionPoint myPoint = getProjectionPoint(TopoDS::Face(GeomShape),gp_XYZ(xe,ye,ze));
+    gp_XY uvPoint = myPoint.uv;
+    gp_XYZ xyzPoint = myPoint.xyz;
+    Standard_Real u0 = uvPoint.X();
+    Standard_Real v0 = uvPoint.Y();
+    Standard_Real x0 = xyzPoint.X();
+    Standard_Real y0 = xyzPoint.Y();
+    Standard_Real z0 = xyzPoint.Z();
+    MESSAGE("Projected Vertex: " << x0 << ", " << y0 << ", " << z0);
+    coords.push_back(u0);
+    coords.push_back(v0);
+    coords.push_back(x0);
+    coords.push_back(y0);
+    coords.push_back(z0);
+  
+    int key = 0;
+    if (! FacesWithEnforcedVertices.Contains(TopoDS::Face(GeomShape))) {
+      key = FacesWithEnforcedVertices.Add(TopoDS::Face(GeomShape));
+    }
+    else {
+      key = FacesWithEnforcedVertices.FindIndex(TopoDS::Face(GeomShape));
+    }
+
+    // If a node is already created by an attractor, do not create enforced vertex
+    int attractorKey = FacesWithSizeMap.FindIndex(TopoDS::Face(GeomShape));
+    bool sameAttractor = false;
+    if (attractorKey >= 0)
+      if (FaceId2AttractorCoords.count(attractorKey) > 0)
+        if (FaceId2AttractorCoords[attractorKey] == coords)
+          sameAttractor = true;
+
+    if (FaceId2EnforcedVertexCoords.find(key) != FaceId2EnforcedVertexCoords.end()) {
+      MESSAGE("Map of enf. vertex has key " << key)
+      MESSAGE("Enf. vertex list size is: " << FaceId2EnforcedVertexCoords[key].size())
+      if (not sameAttractor)
+        FaceId2EnforcedVertexCoords[key].insert(coords); // there should be no redondant coords here (see std::set management)
+      else
+        MESSAGE("An attractor node is already defined: I don't add the enforced vertex");
+      MESSAGE("New Enf. vertex list size is: " << FaceId2EnforcedVertexCoords[key].size())
+    }
+    else {
+      MESSAGE("Map of enf. vertex has not key " << key << ": creating it")
+      if (not sameAttractor) {
+        std::set< std::vector<double> > ens;
+        ens.insert(coords);
+        FaceId2EnforcedVertexCoords[key] = ens;
+      }
+      else
+        MESSAGE("An attractor node is already defined: I don't add the enforced vertex");
+    }
+  }
+}
+
+/////////////////////////////////////////////////////////
+void createAttractorOnFace(TopoDS_Shape GeomShape, std::string AttractorFunction)
+{
+  MESSAGE("Attractor function: "<< AttractorFunction);
+  double xa, ya, za; // Coordinates of attractor point
+  double a, b;       // Attractor parameter
+  bool createNode=false; // To create a node on attractor projection
+  int pos1, pos2;
+  const char *sep = ";";
+  // atIt->second has the following pattern:
+  // ATTRACTOR(xa;ya;za;a;b)
+  // where:
+  // xa;ya;za : coordinates of  attractor
+  // a        : desired size on attractor
+  // b        : distance of influence of attractor
+  //
+  // We search the parameters in the string
+  // xa
+  pos1 = AttractorFunction.find(sep);
+  if (pos1!=string::npos)
+  xa = atof(AttractorFunction.substr(10, pos1-10).c_str());
+  // ya
+  pos2 = AttractorFunction.find(sep, pos1+1);
+  if (pos2!=string::npos) {
+  ya = atof(AttractorFunction.substr(pos1+1, pos2-pos1-1).c_str());
+  pos1 = pos2;
+    }
+  // za
+  pos2 = AttractorFunction.find(sep, pos1+1);
+  if (pos2!=string::npos) {
+  za = atof(AttractorFunction.substr(pos1+1, pos2-pos1-1).c_str());
+  pos1 = pos2;
+  }
+  // a
+  pos2 = AttractorFunction.find(sep, pos1+1);
+  if (pos2!=string::npos) {
+  a = atof(AttractorFunction.substr(pos1+1, pos2-pos1-1).c_str());
+  pos1 = pos2;
+  }
+  // b
+  pos2 = AttractorFunction.find(sep, pos1+1);
+  if (pos2!=string::npos) {
+  b = atof(AttractorFunction.substr(pos1+1, pos2-pos1-1).c_str());
+    pos1 = pos2;
+  }
+  // createNode
+  pos2 = AttractorFunction.find(")");
+  if (pos2!=string::npos) {
+    string createNodeStr = AttractorFunction.substr(pos1+1, pos2-pos1-1);
+    MESSAGE("createNode: " << createNodeStr);
+    createNode = (AttractorFunction.substr(pos1+1, pos2-pos1-1) == "True");
+  }
+
+  // Get the (u,v) values of the attractor on the face
+  projectionPoint myPoint = getProjectionPoint(TopoDS::Face(GeomShape),gp_XYZ(xa,ya,za));
+  gp_XY uvPoint = myPoint.uv;
+  gp_XYZ xyzPoint = myPoint.xyz;
+  Standard_Real u0 = uvPoint.X();
+  Standard_Real v0 = uvPoint.Y();
+  Standard_Real x0 = xyzPoint.X();
+  Standard_Real y0 = xyzPoint.Y();
+  Standard_Real z0 = xyzPoint.Z();
+  std::vector<double> coords;
+  coords.push_back(u0);
+  coords.push_back(v0);
+  coords.push_back(x0);
+  coords.push_back(y0);
+  coords.push_back(z0);
+  // We construct the python function
+  ostringstream attractorFunctionStream;
+  attractorFunctionStream << "def f(u,v): return ";
+  attractorFunctionStream << _smp_phy_size << "-(" << _smp_phy_size <<"-" << a << ")";
+  attractorFunctionStream << "*exp(-((u-("<<u0<<"))*(u-("<<u0<<"))+(v-("<<v0<<"))*(v-("<<v0<<")))/(" << b << "*" << b <<"))";
+
+  MESSAGE("Python function for attractor:" << std::endl << attractorFunctionStream.str());
+
+  int key;
+  if (! FacesWithSizeMap.Contains(TopoDS::Face(GeomShape))) {
+    key = FacesWithSizeMap.Add(TopoDS::Face(GeomShape));
+  }
+  else {
+    key = FacesWithSizeMap.FindIndex(TopoDS::Face(GeomShape));
+  }
+  FaceId2SizeMap[key] =attractorFunctionStream.str();
+  if (createNode) {
+    MESSAGE("Creating node on ("<<x0<<","<<y0<<","<<z0<<")");
+    FaceId2AttractorCoords[key] = coords;
+  }
+}
+
 /////////////////////////////////////////////////////////
 
 void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, blsurf_session_t *bls)
@@ -441,7 +653,6 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, blsu
   blsurf_set_param(bls, "hphy_flag",         to_string(_physicalMesh).c_str());
 //  blsurf_set_param(bls, "hphy_flag",         "2");
   if ((to_string(_physicalMesh))=="2"){
-
     TopoDS_Shape GeomShape;
     TopAbs_ShapeEnum GeomType;
     //
@@ -455,20 +666,90 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, blsu
         MESSAGE("blsurf_set_sizeMap(): " << smIt->first << " = " << smIt->second);
         GeomShape = entryToShape(smIt->first);
         GeomType  = GeomShape.ShapeType();
+        MESSAGE("Geomtype is " << GeomType);
+        int key = -1;
+        // Group Management
+        if (GeomType == TopAbs_COMPOUND){
+          for (TopoDS_Iterator it (GeomShape); it.More(); it.Next()){
+            // Group of faces
+            if (it.Value().ShapeType() == TopAbs_FACE){
+              HasSizeMapOnFace = true;
+              if (! FacesWithSizeMap.Contains(TopoDS::Face(it.Value()))) {
+                key = FacesWithSizeMap.Add(TopoDS::Face(it.Value()));
+              }
+              else {
+                key = FacesWithSizeMap.FindIndex(TopoDS::Face(it.Value()));
+//                 MESSAGE("Face with key " << key << " already in map");
+              }
+              FaceId2SizeMap[key] = smIt->second;
+            }
+            // Group of edges
+            if (it.Value().ShapeType() == TopAbs_EDGE){
+              HasSizeMapOnEdge = true;
+              HasSizeMapOnFace = true;
+              if (! EdgesWithSizeMap.Contains(TopoDS::Edge(it.Value()))) {
+                key = EdgesWithSizeMap.Add(TopoDS::Edge(it.Value()));
+              }
+              else {
+                key = EdgesWithSizeMap.FindIndex(TopoDS::Edge(it.Value()));
+//                 MESSAGE("Edge with key " << key << " already in map");
+              }
+              EdgeId2SizeMap[key] = smIt->second;
+            }
+            // Group of vertices
+            if (it.Value().ShapeType() == TopAbs_VERTEX){
+              HasSizeMapOnVertex = true;
+              HasSizeMapOnEdge = true;
+              HasSizeMapOnFace = true;
+              if (! VerticesWithSizeMap.Contains(TopoDS::Vertex(it.Value()))) {
+                key = VerticesWithSizeMap.Add(TopoDS::Vertex(it.Value()));
+              }
+              else {
+                key = VerticesWithSizeMap.FindIndex(TopoDS::Vertex(it.Value()));
+//                 MESSAGE("Vertex with key " << key << " already in map");
+              }
+              VertexId2SizeMap[key] = smIt->second;
+            }
+          }
+        }
+        // Single face
         if (GeomType == TopAbs_FACE){
           HasSizeMapOnFace = true;
-          FaceId2SizeMap[TopoDS::Face(GeomShape).HashCode(471662)] = smIt->second;
+          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");
+          }
+          FaceId2SizeMap[key] = smIt->second;
         }
+        // Single edge
         if (GeomType == TopAbs_EDGE){
           HasSizeMapOnEdge = true;
           HasSizeMapOnFace = true;
-          EdgeId2SizeMap[TopoDS::Edge(GeomShape).HashCode(471662)] = smIt->second;
+          if (! EdgesWithSizeMap.Contains(TopoDS::Edge(GeomShape))) {
+            key = EdgesWithSizeMap.Add(TopoDS::Edge(GeomShape));
+          }
+          else {
+            key = EdgesWithSizeMap.FindIndex(TopoDS::Edge(GeomShape));
+//             MESSAGE("Edge with key " << key << " already in map");
+          }
+          EdgeId2SizeMap[key] = smIt->second;
         }
+        // Single vertex
         if (GeomType == TopAbs_VERTEX){
           HasSizeMapOnVertex = true;
           HasSizeMapOnEdge   = true;
           HasSizeMapOnFace   = true;
-          VertexId2SizeMap[TopoDS::Vertex(GeomShape).HashCode(471662)] = smIt->second;
+          if (! VerticesWithSizeMap.Contains(TopoDS::Vertex(GeomShape))) {
+            key = VerticesWithSizeMap.Add(TopoDS::Vertex(GeomShape));
+          }
+          else {
+            key = VerticesWithSizeMap.FindIndex(TopoDS::Vertex(GeomShape));
+//             MESSAGE("Vertex with key " << key << " already in map");
+          }
+          VertexId2SizeMap[key] = smIt->second;
         }
       }
     }
@@ -477,73 +758,71 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, blsu
     // Attractors
     //
     MESSAGE("Setting Attractors");
-    const BLSURFPlugin_Hypothesis::TSizeMap & attractors = hyp->GetAttractorEntries();
-    BLSURFPlugin_Hypothesis::TSizeMap::const_iterator atIt;
-    for ( atIt = attractors.begin(); atIt != attractors.end(); ++atIt ) {
+    const BLSURFPlugin_Hypothesis::TSizeMap attractors = BLSURFPlugin_Hypothesis::GetAttractorEntries(hyp);
+    BLSURFPlugin_Hypothesis::TSizeMap::const_iterator atIt = attractors.begin();
+    for ( ; atIt != attractors.end(); ++atIt ) {
       if ( !atIt->second.empty() ) {
         MESSAGE("blsurf_set_attractor(): " << atIt->first << " = " << atIt->second);
         GeomShape = entryToShape(atIt->first);
         GeomType  = GeomShape.ShapeType();
-
+        // Group Management
+        if (GeomType == TopAbs_COMPOUND){
+          for (TopoDS_Iterator it (GeomShape); it.More(); it.Next()){
+            if (it.Value().ShapeType() == TopAbs_FACE){
+              HasSizeMapOnFace = true;
+              createAttractorOnFace(it.Value(), atIt->second);
+            }
+          }
+        }
+               
         if (GeomType == TopAbs_FACE){
           HasSizeMapOnFace = true;
-
-          double xa, ya, za; // Coordinates of attractor point
-          double a, b;       // Attractor parameter
-          int pos1, pos2;
-          // atIt->second has the following pattern:
-          // ATTRACTOR(xa;ya;za;a;b)
-          // where:
-          // xa;ya;za : coordinates of  attractor
-          // a        : desired size on attractor
-          // b        : distance of influence of attractor
-          //
-          // We search the parameters in the string
-          pos1 = atIt->second.find(";");
-          xa = atof(atIt->second.substr(10, pos1-10).c_str());
-          pos2 = atIt->second.find(";", pos1+1);
-          ya = atof(atIt->second.substr(pos1+1, pos2-pos1-1).c_str());
-          pos1 = pos2;
-          pos2 = atIt->second.find(";", pos1+1);
-          za = atof(atIt->second.substr(pos1+1, pos2-pos1-1).c_str());
-          pos1 = pos2;
-          pos2 = atIt->second.find(";", pos1+1);
-          a = atof(atIt->second.substr(pos1+1, pos2-pos1-1).c_str());
-          pos1 = pos2;
-          pos2 = atIt->second.find(")");
-          b = atof(atIt->second.substr(pos1+1, pos2-pos1-1).c_str());
-
-          // Get the (u,v) values of the attractor on the face
-          gp_XY uvPoint = getUV(TopoDS::Face(GeomShape),gp_XYZ(xa,ya,za));
-          Standard_Real u0 = uvPoint.X();
-          Standard_Real v0 = uvPoint.Y();
-          // We construct the python function
-          ostringstream attractorFunction;
-          attractorFunction << "def f(u,v): return ";
-          attractorFunction << _smp_phy_size << "-(" << _smp_phy_size <<"-" << a << ")";
-          attractorFunction << "*exp(-((u-("<<u0<<"))*(u-("<<u0<<"))+(v-("<<v0<<"))*(v-("<<v0<<")))/(" << b << "*" << b <<"))";
-
-          MESSAGE("Python function for attractor:" << std::endl << attractorFunction.str());
-
-          FaceId2SizeMap[TopoDS::Face(GeomShape).HashCode(471662)] =attractorFunction.str();
+          createAttractorOnFace(GeomShape, atIt->second);
         }
 /*
         if (GeomType == TopAbs_EDGE){
           HasSizeMapOnEdge = true;
           HasSizeMapOnFace = true;
-        EdgeId2SizeMap[TopoDS::Edge(GeomShape).HashCode(471662)] = atIt->second;
+        EdgeId2SizeMap[TopoDS::Edge(GeomShape).HashCode(IntegerLast())] = atIt->second;
         }
         if (GeomType == TopAbs_VERTEX){
           HasSizeMapOnVertex = true;
           HasSizeMapOnEdge   = true;
           HasSizeMapOnFace   = true;
-        VertexId2SizeMap[TopoDS::Vertex(GeomShape).HashCode(471662)] = atIt->second;
+        VertexId2SizeMap[TopoDS::Vertex(GeomShape).HashCode(IntegerLast())] = atIt->second;
         }
 */
       }
     }
 
 
+    //
+    // Enforced Vertices
+    //
+    MESSAGE("Setting Enforced Vertices");
+    const BLSURFPlugin_Hypothesis::TEnforcedVertexMap enforcedVertexMap = BLSURFPlugin_Hypothesis::GetAllEnforcedVertices(hyp);
+    BLSURFPlugin_Hypothesis::TEnforcedVertexMap::const_iterator enfIt = enforcedVertexMap.begin();
+    for ( ; enfIt != enforcedVertexMap.end(); ++enfIt ) {
+      if ( !enfIt->second.empty() ) {
+        GeomShape = entryToShape(enfIt->first);
+        GeomType  = GeomShape.ShapeType();
+        // Group Management
+        if (GeomType == TopAbs_COMPOUND){
+          for (TopoDS_Iterator it (GeomShape); it.More(); it.Next()){
+            if (it.Value().ShapeType() == TopAbs_FACE){
+              HasSizeMapOnFace = true;
+              createEnforcedVertexOnFace(it.Value(), enfIt->second);
+            }
+          }
+        }
+            
+        if (GeomType == TopAbs_FACE){
+          HasSizeMapOnFace = true;
+          createEnforcedVertexOnFace(GeomShape, enfIt->second);
+        }
+      }
+    }
+
 //    if (HasSizeMapOnFace){
     // In all size map cases (hphy_flag = 2), at least map on face must be defined
     MESSAGE("Setting Size Map on FACES ");
@@ -599,8 +878,16 @@ bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape)
 
   blsurf_session_t *bls = blsurf_session_new(ctx);
 
+  FacesWithSizeMap.Clear();
+  FaceId2SizeMap.clear();
+  EdgesWithSizeMap.Clear();
+  EdgeId2SizeMap.clear();
+  VerticesWithSizeMap.Clear();
+  VertexId2SizeMap.clear();
 
+  MESSAGE("BEGIN SetParameters");
   SetParameters(_hypothesis, bls);
+  MESSAGE("END SetParameters");
 
   TopTools_IndexedMapOfShape fmap;
   TopTools_IndexedMapOfShape emap;
@@ -608,8 +895,6 @@ bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape)
   vector<Handle(Geom2d_Curve)> curves;
   vector<Handle(Geom_Surface)> surfaces;
 
-
-
   fmap.Clear();
   FaceId2PythonSmp.clear();
   emap.Clear();
@@ -622,42 +907,25 @@ bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape)
   assert(Py_IsInitialized());
   PyGILState_STATE gstate;
   gstate = PyGILState_Ensure();
-/*
-  Standard_Real u_min;
-  Standard_Real v_min;
-  Standard_Real u_max;
-  Standard_Real v_max;
-*/
+
+  string theSizeMapStr;
+  
+  /****************************************************************************************
+                                  FACES
+  *****************************************************************************************/
   int iface = 0;
   string bad_end = "return";
+  int faceKey = -1;
   for (TopExp_Explorer face_iter(aShape,TopAbs_FACE);face_iter.More();face_iter.Next()) {
     TopoDS_Face f=TopoDS::Face(face_iter.Current());
+    
     if (fmap.FindIndex(f) > 0)
       continue;
 
     fmap.Add(f);
     iface++;
     surfaces.push_back(BRep_Tool::Surface(f));
-    // Get bound values of uv surface
-    //BRep_Tool::Surface(f)->Bounds(u_min,u_max,v_min,v_max);
-    //MESSAGE("BRep_Tool::Surface(f)->Bounds(u_min,u_max,v_min,v_max): " << u_min << ", " << u_max << ", " << v_min << ", " << v_max);
-
-    if ((HasSizeMapOnFace) && FaceId2SizeMap.find(f.HashCode(471662))!=FaceId2SizeMap.end()){
-        MESSAGE("FaceId2SizeMap[f.HashCode(471662)].find(bad_end): " << FaceId2SizeMap[f.HashCode(471662)].find(bad_end));
-        MESSAGE("FaceId2SizeMap[f.HashCode(471662)].size(): " << FaceId2SizeMap[f.HashCode(471662)].size());
-        MESSAGE("bad_end.size(): " << bad_end.size());
-      // check if function ends with "return"
-        if (FaceId2SizeMap[f.HashCode(471662)].find(bad_end) == (FaceId2SizeMap[f.HashCode(471662)].size()-bad_end.size()-1))
-        continue;
-      // Expr To Python function, verification is performed at validation in GUI
-      PyObject * obj = NULL;
-      obj= PyRun_String(FaceId2SizeMap[f.HashCode(471662)].c_str(), Py_file_input, main_dict, NULL);
-      Py_DECREF(obj);
-      PyObject * func = NULL;
-      func = PyObject_GetAttrString(main_mod, "f");
-      FaceId2PythonSmp[iface]=func;
-      FaceId2SizeMap.erase(f.HashCode(471662));
-    }
+
     cad_face_t *fce = cad_face_new(c, iface, surf_fun, surfaces.back());
     cad_face_set_tag(fce, iface);
     if(f.Orientation() != TopAbs_FORWARD){
@@ -665,26 +933,148 @@ bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape)
     } else {
       cad_face_set_orientation(fce, CAD_ORIENTATION_FORWARD);
     }
-
+    
+    if (HasSizeMapOnFace){
+      std::cout << "A size map is defined on a face" << std::endl;
+      // Classic size map
+      faceKey = FacesWithSizeMap.FindIndex(f);
+      
+      if (FaceId2SizeMap.find(faceKey)!=FaceId2SizeMap.end()){
+        theSizeMapStr = FaceId2SizeMap[faceKey];
+        // check if function ends with "return"
+        if (theSizeMapStr.find(bad_end) == (theSizeMapStr.size()-bad_end.size()-1))
+          continue;
+        // Expr To Python function, verification is performed at validation in GUI
+        PyObject * obj = NULL;
+        obj= PyRun_String(theSizeMapStr.c_str(), Py_file_input, main_dict, NULL);
+        Py_DECREF(obj);
+        PyObject * func = NULL;
+        func = PyObject_GetAttrString(main_mod, "f");
+        FaceId2PythonSmp[iface]=func;
+        FaceId2SizeMap.erase(faceKey);
+      }
+      
+      // Specific size map = Attractor
+      std::map<int,std::vector<double> >::iterator attractor_iter = FaceId2AttractorCoords.begin();
+      int iatt=0;
+      for (; attractor_iter != FaceId2AttractorCoords.end(); ++attractor_iter) {
+        if (attractor_iter->first == faceKey) {
+          MESSAGE("Face indice: " << iface);
+          MESSAGE("Adding attractor");
+          
+          double xyzCoords[3]  = {attractor_iter->second[2],
+                                  attractor_iter->second[3],
+                                  attractor_iter->second[4]};
+          
+          MESSAGE("Check position of vertex =(" << xyzCoords[0] << "," << xyzCoords[1] << "," << xyzCoords[2] << ")");
+          gp_Pnt P(xyzCoords[0],xyzCoords[1],xyzCoords[2]);
+          BRepClass_FaceClassifier scl(f,P,1e-7);
+          // scl.Perform() is bugged. The function was rewritten
+//          scl.Perform();
+          BRepClass_FaceClassifierPerform(&scl,f,P,1e-7);
+          TopAbs_State result = scl.State();
+          MESSAGE("Position of point on face: "<<result);
+          if ( result == TopAbs_OUT )
+              MESSAGE("Point is out of face: node is not created");
+          if ( result == TopAbs_UNKNOWN )
+              MESSAGE("Point position on face is unknown: node is not created");
+          if ( result == TopAbs_ON )
+              MESSAGE("Point is on border of face: node is not created");
+          if ( result == TopAbs_IN )
+          {
+            // Point is inside face and not on border
+            MESSAGE("Point is in face: node is created");
+            double uvCoords[2]   = {attractor_iter->second[0],attractor_iter->second[1]};
+            iatt++;
+            MESSAGE("Add cad point on (u,v)=(" << uvCoords[0] << "," << uvCoords[1] << ") with id = " << iatt);
+            cad_point_t* point_p = cad_point_new(fce, iatt, uvCoords);
+            cad_point_set_tag(point_p, iatt);
+          }
+          FaceId2AttractorCoords.erase(faceKey);
+        }
+      }
+      
+      // Enforced Vertices
+      faceKey = FacesWithEnforcedVertices.FindIndex(f);
+      std::map<int,std::set<std::vector<double> > >::const_iterator evmIt = FaceId2EnforcedVertexCoords.find(faceKey);
+      if (evmIt != FaceId2EnforcedVertexCoords.end()) {
+        std::cout << "Some enforced vertices are defined" << std::endl;
+        int ienf = 0;
+        std::set<std::vector<double> > evl;
+//         std::vector<double> ev;
+        MESSAGE("Face indice: " << iface);
+        MESSAGE("Adding enforced vertices");
+        evl = evmIt->second;
+        MESSAGE("Number of vertices to add: "<< evl.size())
+        std::set< std::vector<double> >::const_iterator evlIt = evl.begin();
+        for (; evlIt != evl.end(); ++evlIt) {
+//           ev = *evlIt;
+//         for (int i=0; i<evl.size() ; i++) {
+//           ev = evl[i];
+          
+//           double xyzCoords[3]  = {ev[2], ev[3], ev[4]};
+          double xyzCoords[3]  = {evlIt->at(0), evlIt->at(3), evlIt->at(4)};
+          MESSAGE("Check position of vertex =(" << xyzCoords[0] << "," << xyzCoords[1] << "," << xyzCoords[2] << ")");
+          gp_Pnt P(xyzCoords[0],xyzCoords[1],xyzCoords[2]);
+          BRepClass_FaceClassifier scl(f,P,1e-7);
+          // scl.Perform() is bugged. The function was rewritten
+//          scl.Perform();
+          BRepClass_FaceClassifierPerform(&scl,f,P,1e-7);
+          TopAbs_State result = scl.State();
+          MESSAGE("Position of point on face: "<<result);
+          if ( result == TopAbs_OUT )
+              MESSAGE("Point is out of face: node is not created");
+          if ( result == TopAbs_UNKNOWN )
+              MESSAGE("Point position on face is unknown: node is not created");
+          if ( result == TopAbs_ON )
+              MESSAGE("Point is on border of face: node is not created");
+          if ( result == TopAbs_IN )
+          {
+            // Point is inside face and not on border
+            MESSAGE("Point is in face: node is created");
+//             double uvCoords[2]   = {ev[0],ev[1]};
+            double uvCoords[2]   = {evlIt->at(0),evlIt->at(1)};
+            ienf++;
+            MESSAGE("Add cad point on (u,v)=(" << uvCoords[0] << "," << uvCoords[1] << ") with id = " << ienf);
+            cad_point_t* point_p = cad_point_new(fce, ienf, uvCoords);
+            cad_point_set_tag(point_p, ienf);
+          }
+        }
+        FaceId2EnforcedVertexCoords.erase(faceKey);
+      }
+      else
+        std::cout << "No enforced vertex defined" << std::endl;
+    }
+    
+    
+    /****************************************************************************************
+                                    EDGES
+    *****************************************************************************************/
+    int edgeKey = -1;
     for (TopExp_Explorer edge_iter(f,TopAbs_EDGE);edge_iter.More();edge_iter.Next()) {
       TopoDS_Edge e = TopoDS::Edge(edge_iter.Current());
       int ic = emap.FindIndex(e);
       if (ic <= 0)
-       ic = emap.Add(e);
+        ic = emap.Add(e);
 
       double tmin,tmax;
       curves.push_back(BRep_Tool::CurveOnSurface(e, f, tmin, tmax));
-      if ((HasSizeMapOnEdge) && EdgeId2SizeMap.find(e.HashCode(471662))!=EdgeId2SizeMap.end()){
-          if (EdgeId2SizeMap[e.HashCode(471662)].find(bad_end) == (EdgeId2SizeMap[e.HashCode(471662)].size()-bad_end.size()-1))
-          continue;
-        // Expr To Python function, verification is performed at validation in GUI
-        PyObject * obj = NULL;
-        obj= PyRun_String(EdgeId2SizeMap[e.HashCode(471662)].c_str(), Py_file_input, main_dict, NULL);
-        Py_DECREF(obj);
-        PyObject * func = NULL;
-        func = PyObject_GetAttrString(main_mod, "f");
-        EdgeId2PythonSmp[ic]=func;
-        EdgeId2SizeMap.erase(e.HashCode(471662));
+      
+      if (HasSizeMapOnEdge){
+        edgeKey = EdgesWithSizeMap.FindIndex(e);
+        if (EdgeId2SizeMap.find(edgeKey)!=EdgeId2SizeMap.end()) {
+          theSizeMapStr = EdgeId2SizeMap[faceKey];
+          if (theSizeMapStr.find(bad_end) == (theSizeMapStr.size()-bad_end.size()-1))
+            continue;
+          // Expr To Python function, verification is performed at validation in GUI
+          PyObject * obj = NULL;
+          obj= PyRun_String(theSizeMapStr.c_str(), Py_file_input, main_dict, NULL);
+          Py_DECREF(obj);
+          PyObject * func = NULL;
+          func = PyObject_GetAttrString(main_mod, "f");
+          EdgeId2PythonSmp[ic]=func;
+          EdgeId2SizeMap.erase(edgeKey);
+        }
       }
       cad_edge_t *edg = cad_edge_new(fce, ic, tmin, tmax, curv_fun, curves.back());
       cad_edge_set_tag(edg, ic);
@@ -697,40 +1087,52 @@ bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape)
       gp_Pnt2d e0 = curves.back()->Value(tmin);
       gp_Pnt ee0 = surfaces.back()->Value(e0.X(), e0.Y());
       Standard_Real d1=0,d2=0;
+      
+      
+      /****************************************************************************************
+                                      VERTICES
+      *****************************************************************************************/
+      int vertexKey = -1;
       for (TopExp_Explorer ex_edge(e ,TopAbs_VERTEX); ex_edge.More(); ex_edge.Next()) {
-       TopoDS_Vertex v = TopoDS::Vertex(ex_edge.Current());
-       ++npts;
-       if (npts == 1){
-         ip = &ip1;
-         d1 = ee0.SquareDistance(BRep_Tool::Pnt(v));
-       } else {
-         ip = &ip2;
+        TopoDS_Vertex v = TopoDS::Vertex(ex_edge.Current());
+        ++npts;
+        if (npts == 1){
+          ip = &ip1;
+          d1 = ee0.SquareDistance(BRep_Tool::Pnt(v));
+        } else {
+          ip = &ip2;
           d2 = ee0.SquareDistance(BRep_Tool::Pnt(v));
-       }
-       *ip = pmap.FindIndex(v);
-       if(*ip <= 0)
-         *ip = pmap.Add(v);
-    if ((HasSizeMapOnVertex) && VertexId2SizeMap.find(v.HashCode(471662))!=VertexId2SizeMap.end()){
-        if (VertexId2SizeMap[v.HashCode(471662)].find(bad_end) == (VertexId2SizeMap[v.HashCode(471662)].size()-bad_end.size()-1))
-            continue;
-          // Expr To Python function, verification is performed at validation in GUI
-          PyObject * obj = NULL;
-          obj= PyRun_String(VertexId2SizeMap[v.HashCode(471662)].c_str(), Py_file_input, main_dict, NULL);
-          Py_DECREF(obj);
-          PyObject * func = NULL;
-          func = PyObject_GetAttrString(main_mod, "f");
-          VertexId2PythonSmp[*ip]=func;
-          VertexId2SizeMap.erase(v.HashCode(471662));
+        }
+        *ip = pmap.FindIndex(v);
+        if(*ip <= 0)
+          *ip = pmap.Add(v);
+        
+        vertexKey = VerticesWithSizeMap.FindIndex(v);
+        if (HasSizeMapOnVertex){
+          vertexKey = VerticesWithSizeMap.FindIndex(v);
+          if (VertexId2SizeMap.find(vertexKey)!=VertexId2SizeMap.end()){
+            theSizeMapStr = VertexId2SizeMap[faceKey];
+            if (theSizeMapStr.find(bad_end) == (theSizeMapStr.size()-bad_end.size()-1))
+              continue;
+            // Expr To Python function, verification is performed at validation in GUI
+            PyObject * obj = NULL;
+            obj= PyRun_String(theSizeMapStr.c_str(), Py_file_input, main_dict, NULL);
+            Py_DECREF(obj);
+            PyObject * func = NULL;
+            func = PyObject_GetAttrString(main_mod, "f");
+            VertexId2PythonSmp[*ip]=func;
+//             VertexId2SizeMap.erase(vertexKey);   // do not erase if using a vector
+          }
         }
       }
       if (npts != 2) {
-       // should not happen
-       MESSAGE("An edge does not have 2 extremities.");
+        // should not happen
+        MESSAGE("An edge does not have 2 extremities.");
       } else {
-       if (d1 < d2)
-         cad_edge_set_extremities(edg, ip1, ip2);
-       else
-         cad_edge_set_extremities(edg, ip2, ip1);
+        if (d1 < d2)
+          cad_edge_set_extremities(edg, ip1, ip2);
+        else
+          cad_edge_set_extremities(edg, ip2, ip1);
       }
     } // for edge
   } //for face
@@ -750,7 +1152,7 @@ bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape)
   int oldFEFlags = fedisableexcept( FE_ALL_EXCEPT );
 #endif
 
-    status_t status = STATUS_ERROR;
+  status_t status = STATUS_ERROR;
 
   try {
     OCC_CATCH_SIGNALS;
@@ -897,7 +1299,16 @@ bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape)
     feenableexcept( oldFEFlags );
   feclearexcept( FE_ALL_EXCEPT );
 #endif
-
+  
+  std::cout << "FacesWithSizeMap" << std::endl;
+  FacesWithSizeMap.Statistics(std::cout);
+  std::cout << "EdgesWithSizeMap" << std::endl;
+  EdgesWithSizeMap.Statistics(std::cout);
+  std::cout << "VerticesWithSizeMap" << std::endl;
+  VerticesWithSizeMap.Statistics(std::cout);
+  std::cout << "FacesWithEnforcedVertices" << std::endl;
+  FacesWithEnforcedVertices.Statistics(std::cout);
+  
   return true;
 }
 
@@ -1301,3 +1712,53 @@ bool BLSURFPlugin_BLSURF::Evaluate(SMESH_Mesh& aMesh,
 
   return true;
 }
+
+//=============================================================================
+/*!
+ *  Rewritting of the BRepClass_FaceClassifier::Perform function which is bugged (CAS 6.3sp6)
+ *  Following line was added:
+ *        myExtrem.Perform(P);
+ */
+//=============================================================================
+void  BLSURFPlugin_BLSURF::BRepClass_FaceClassifierPerform(BRepClass_FaceClassifier* fc,
+                    const TopoDS_Face& face, 
+                    const gp_Pnt& P, 
+                    const Standard_Real Tol)
+{
+  //-- Voir BRepExtrema_ExtPF.cxx 
+  BRepAdaptor_Surface Surf(face);
+  Standard_Real U1, U2, V1, V2;
+  BRepTools::UVBounds(face, U1, U2, V1, V2);
+  Extrema_ExtPS myExtrem;
+  myExtrem.Initialize(Surf, U1, U2, V1, V2, Tol, Tol);
+  myExtrem.Perform(P);
+  //----------------------------------------------------------
+  //-- On cherche le point le plus proche , PUIS 
+  //-- On le classifie. 
+  Standard_Integer nbv    = 0; // xpu
+  Standard_Real MaxDist   =  RealLast();
+  Standard_Integer indice = 0;
+  if(myExtrem.IsDone()) {
+    nbv = myExtrem.NbExt();
+    for (Standard_Integer i = 1; i <= nbv; i++) {
+      Standard_Real d = myExtrem.Value(i);
+      d = Abs(d);
+      if(d <= MaxDist) { 
+    MaxDist = d;
+    indice = i;
+      }
+    }
+  }
+  if(indice) { 
+    gp_Pnt2d Puv;
+    Standard_Real U1,U2;
+    myExtrem.Point(indice).Parameter(U1, U2);
+    Puv.SetCoord(U1, U2);
+    fc->Perform(face, Puv, Tol);
+  }
+  else { 
+    fc->Perform(face, gp_Pnt2d(U1-1.0,V1 - 1.0), Tol); //-- NYI etc BUG PAS BEAU En attendant l acces a rejected
+    //-- le resultat est TopAbs_OUT;
+  }
+}
+
index bb81452ac8f9ae78ac9027b77186f8ed5dabb88f..01a17d22b6d0030d4142707d307ba54a74357417 100644 (file)
@@ -50,7 +50,13 @@ extern "C"{
 #include "distene/api.h"
 }
 
+#include <BRepClass_FaceClassifier.hxx>
+#include <BRepAdaptor_Surface.hxx>
+#include <BRepTools.hxx>
+#include <BRepAdaptor_HSurface.hxx>
+
 class BLSURFPlugin_Hypothesis;
+class TopoDS_Shape;
 
 class BLSURFPlugin_BLSURF: public SMESH_2D_Algo {
   public:
@@ -81,6 +87,7 @@ class BLSURFPlugin_BLSURF: public SMESH_2D_Algo {
 
   private:
     void Set_NodeOnEdge(SMESHDS_Mesh* meshDS, SMDS_MeshNode* node, const TopoDS_Shape& ed);
+    void BRepClass_FaceClassifierPerform(BRepClass_FaceClassifier* fc, const TopoDS_Face& face, const gp_Pnt& P, const Standard_Real Tol);
 
   private:
       PyObject *          main_mod;
index ae1d60e33dd2732ffa13e8bb95b066207728afe6..5eef8fff8d2af593a20419203fef6c61af278a53 100644 (file)
@@ -26,6 +26,8 @@
 #include "BLSURFPlugin_Hypothesis.hxx"
 #include <utilities.h>
 #include <cstring>
+#include <iostream>
+#include <sstream>
 
 //=============================================================================
 BLSURFPlugin_Hypothesis::BLSURFPlugin_Hypothesis (int hypId, int studyId,
@@ -44,14 +46,17 @@ BLSURFPlugin_Hypothesis::BLSURFPlugin_Hypothesis (int hypId, int studyId,
     _gradation(GetDefaultGradation()),
     _quadAllowed(GetDefaultQuadAllowed()),
     _decimesh(GetDefaultDecimesh()),
-    _verb( GetDefaultVerbosity() )
+    _verb( GetDefaultVerbosity() ),
+    _sizeMap(GetDefaultSizeMap()),
+    _attractors(GetDefaultSizeMap()),
+    _enforcedVertices(GetDefaultEnforcedVertexMap())
 {
   _name = "BLSURF_Parameters";
   _param_algo_dim = 2;
 
   // to desable writing boundaries
   //_phyMin = _phyMax = _hgeoMin = _hgeoMax = undefinedDouble();
-  
+
 
   const char* intOptionNames[] = {
     "addsurf_ivertex",
@@ -122,7 +127,7 @@ BLSURFPlugin_Hypothesis::BLSURFPlugin_Hypothesis (int hypId, int studyId,
     _charOptions.insert( charOptionNames[i] );
     _option2value[ charOptionNames[i++] ].clear();
   }
-  
+
   _sizeMap.clear();
 }
 
@@ -144,6 +149,7 @@ void BLSURFPlugin_Hypothesis::SetPhysicalMesh(PhysicalMesh thePhysicalMesh)
       case DefaultSize:
       default:
         _phySize = GetDefaultPhySize();
+        _gradation  = GetDefaultGradation();
         break;
       }
     NotifySubMeshesHypothesisModification();
@@ -337,7 +343,9 @@ void BLSURFPlugin_Hypothesis::ClearOption(const std::string& optionName)
     op_val->second.clear();
 }
 
-
+//=======================================================================
+//function : SetSizeMapEntry
+//=======================================================================
 void  BLSURFPlugin_Hypothesis::SetSizeMapEntry(const std::string& entry,const std::string& sizeMap)
 {
   if (_sizeMap[entry].compare(sizeMap) != 0) {
@@ -346,6 +354,9 @@ void  BLSURFPlugin_Hypothesis::SetSizeMapEntry(const std::string& entry,const st
   }
 }
 
+//=======================================================================
+//function : GetSizeMapEntry
+//=======================================================================
 std::string  BLSURFPlugin_Hypothesis::GetSizeMapEntry(const std::string& entry)
 {
  TSizeMap::iterator it  = _sizeMap.find( entry );
@@ -355,6 +366,17 @@ std::string  BLSURFPlugin_Hypothesis::GetSizeMapEntry(const std::string& entry)
    return "No_Such_Entry";
 }
 
+  /*!
+   * \brief Return the size maps
+   */
+BLSURFPlugin_Hypothesis::TSizeMap BLSURFPlugin_Hypothesis::GetSizeMapEntries(const BLSURFPlugin_Hypothesis* hyp)
+{
+    return hyp ? hyp->_GetSizeMapEntries():GetDefaultSizeMap();
+}
+
+//=======================================================================
+//function : SetAttractorEntry
+//=======================================================================
 void  BLSURFPlugin_Hypothesis::SetAttractorEntry(const std::string& entry,const std::string& attractor)
 {
   if (_attractors[entry].compare(attractor) != 0) {
@@ -363,6 +385,9 @@ void  BLSURFPlugin_Hypothesis::SetAttractorEntry(const std::string& entry,const
   }
 }
 
+//=======================================================================
+//function : GetAttractorEntry
+//=======================================================================
 std::string  BLSURFPlugin_Hypothesis::GetAttractorEntry(const std::string& entry)
 {
  TSizeMap::iterator it  = _attractors.find( entry );
@@ -372,6 +397,15 @@ std::string  BLSURFPlugin_Hypothesis::GetAttractorEntry(const std::string& entry
    return "No_Such_Entry";
 }
 
+  /*!
+   * \brief Return the attractors
+   */
+BLSURFPlugin_Hypothesis::TSizeMap BLSURFPlugin_Hypothesis::GetAttractorEntries(const BLSURFPlugin_Hypothesis* hyp)
+{
+    return hyp ? hyp->_GetAttractorEntries():GetDefaultSizeMap();
+}
+
+
 
 void BLSURFPlugin_Hypothesis::ClearEntry(const std::string& entry)
 {
@@ -400,6 +434,174 @@ void BLSURFPlugin_Hypothesis::ClearSizeMaps()
 
 
 
+//=======================================================================
+//function : SetEnforcedVertex
+//=======================================================================
+
+void BLSURFPlugin_Hypothesis::SetEnforcedVertex(const std::string& entry, double x, double y, double z)
+{
+  BLSURFPlugin_Hypothesis::TEnforcedVertex coord;
+  coord.push_back(x);
+  coord.push_back(y);
+  coord.push_back(z);
+  bool toNotify = false;
+  if (_enforcedVertices.count(entry)>0)
+    if (_enforcedVertices[entry].count(coord)==0)
+      toNotify = true;
+  else
+    toNotify = true;
+  
+  _enforcedVertices[entry].insert(coord);
+  if (toNotify)
+    NotifySubMeshesHypothesisModification();
+}
+
+/*
+//=======================================================================
+//function : SetEnforcedVertexList
+//=======================================================================
+
+void BLSURFPlugin_Hypothesis::SetEnforcedVertexList(const std::string& entry, const BLSURFPlugin_Hypothesis::TEnforcedVertexList vertexList)
+{
+  BLSURFPlugin_Hypothesis::TEnforcedVertexList::const_iterator it;
+  bool toNotify = false;
+  for(it = vertexList.begin();it!=vertexList.end();++it) {
+    if (_enforcedVertices.count(entry)>0)
+      if (_enforcedVertices[entry].count(*it)==0)
+        toNotify = true;
+    else
+      toNotify = true;
+    _enforcedVertices[entry].insert(*it);
+  }
+  if (toNotify)
+    NotifySubMeshesHypothesisModification();
+}
+*/
+
+//=======================================================================
+//function : GetEnforcedVertices
+//=======================================================================
+
+BLSURFPlugin_Hypothesis::TEnforcedVertexList BLSURFPlugin_Hypothesis::GetEnforcedVertices(const std::string& entry)
+  throw (std::invalid_argument)
+{
+  if (_enforcedVertices.count(entry)>0)
+    return _enforcedVertices[entry];
+  std::ostringstream msg ;
+  msg << "No enforced vertex for entry " << entry ;
+  throw std::invalid_argument(msg.str());
+}
+
+//=======================================================================
+//function : ClearEnforcedVertex
+//=======================================================================
+
+void BLSURFPlugin_Hypothesis::ClearEnforcedVertex(const std::string& entry, double x, double y, double z)
+  throw (std::invalid_argument)
+{
+  BLSURFPlugin_Hypothesis::TEnforcedVertex coord;
+  coord.push_back(x);
+  coord.push_back(y);
+  coord.push_back(z);
+  BLSURFPlugin_Hypothesis::TEnforcedVertexList::iterator it;
+  bool toNotify = false;
+
+  BLSURFPlugin_Hypothesis::TEnforcedVertexMap::iterator it_enf = _enforcedVertices.find(entry);
+  if (it_enf != _enforcedVertices.end()) {
+    it = _enforcedVertices[entry].find(coord);
+    if (it != _enforcedVertices[entry].end()) {
+      toNotify = true;
+      _enforcedVertices[entry].erase(it);
+      if (_enforcedVertices[entry].size() == 0)
+        _enforcedVertices.erase(it_enf);
+    }
+    if (toNotify)
+      NotifySubMeshesHypothesisModification();
+    return;
+  }
+
+  std::ostringstream msg ;
+  msg << "No enforced vertex for " << entry;
+  throw std::invalid_argument(msg.str());
+}
+/*
+//=======================================================================
+//function : ClearEnforcedVertexList
+//=======================================================================
+
+void BLSURFPlugin_Hypothesis::ClearEnforcedVertexList(const std::string& entry, BLSURFPlugin_Hypothesis::TEnforcedVertexList vertexList)
+  throw (std::invalid_argument)
+{
+  BLSURFPlugin_Hypothesis::TEnforcedVertex coord;
+  BLSURFPlugin_Hypothesis::TEnforcedVertexList::const_iterator it_toRemove;
+  BLSURFPlugin_Hypothesis::TEnforcedVertexList::iterator it;
+  bool toNotify = false;
+
+  BLSURFPlugin_Hypothesis::TEnforcedVertexMap::iterator it_enf = _enforcedVertices.find(entry);
+  if (it_enf != _enforcedVertices.end()) {
+    for (it_toRemove = vertexList.begin() ; it_toRemove != vertexList.end() ; ++it_toRemove) {
+      coord = *it_toRemove;
+      it = _enforcedVertices[entry].find(coord);
+      if (it != _enforcedVertices[entry].end()) {
+        toNotify = true;
+        _enforcedVertices[entry].erase(it);
+      }
+    }
+    if (_enforcedVertices[entry].size() == 0) {
+      toNotify = true;
+      _enforcedVertices.erase(it_enf);
+    }
+    if (toNotify)
+      NotifySubMeshesHypothesisModification();
+    return;
+  }
+
+  std::ostringstream msg ;
+  msg << "No enforced vertex for " << entry;
+  throw std::invalid_argument(msg.str());
+}
+*/
+//=======================================================================
+//function : ClearEnforcedVertices
+//=======================================================================
+
+void BLSURFPlugin_Hypothesis::ClearEnforcedVertices(const std::string& entry)
+  throw (std::invalid_argument)
+{
+  BLSURFPlugin_Hypothesis::TEnforcedVertexMap::iterator it_enf = _enforcedVertices.find(entry);
+  if (it_enf != _enforcedVertices.end()) {
+    _enforcedVertices.erase(it_enf);
+    NotifySubMeshesHypothesisModification();
+    return;
+  }
+
+  std::ostringstream msg ;
+  msg << "No enforced vertex for " << entry;
+  throw std::invalid_argument(msg.str());
+}
+
+//=======================================================================
+//function : ClearAllEnforcedVertices
+//=======================================================================
+void BLSURFPlugin_Hypothesis::ClearAllEnforcedVertices()
+{
+    _enforcedVertices.clear();
+    NotifySubMeshesHypothesisModification();
+}
+
+//================================================================================
+/*!
+* \brief Return the enforced vertices
+*/
+//================================================================================
+
+BLSURFPlugin_Hypothesis::TEnforcedVertexMap BLSURFPlugin_Hypothesis::GetAllEnforcedVertices(const BLSURFPlugin_Hypothesis* hyp)
+{
+    return hyp ? hyp->_GetAllEnforcedVertices():GetDefaultEnforcedVertexMap();
+}
+
+
+
 //=============================================================================
 std::ostream & BLSURFPlugin_Hypothesis::SaveTo(std::ostream & save)
 {
@@ -407,9 +609,9 @@ std::ostream & BLSURFPlugin_Hypothesis::SaveTo(std::ostream & save)
        << " " << (int)_physicalMesh
        << " " << (int)_geometricMesh
        << " " << _phySize
-       << " " << _angleMeshS   
-       << " " << _gradation     
-       << " " << (int)_quadAllowed 
+       << " " << _angleMeshS
+       << " " << _gradation
+       << " " << (int)_quadAllowed
        << " " << (int)_decimesh;
   save << " " << _phyMin
        << " " << _phyMax
@@ -448,8 +650,27 @@ std::ostream & BLSURFPlugin_Hypothesis::SaveTo(std::ostream & save)
     }
     save << " " << "__ATTRACTORS_END__";
   }
-  
-  
+
+  TEnforcedVertexMap::const_iterator it_enf = _enforcedVertices.begin();
+  if (it_enf != _enforcedVertices.end()) {
+    save << " " << "__ENFORCED_VERTICES_BEGIN__";
+    for ( ; it_enf != _enforcedVertices.end(); ++it_enf ) {
+      save << " " << it_enf->first;
+      TEnforcedVertexList evl = it_enf->second;
+      TEnforcedVertexList::const_iterator it_evl = evl.begin();
+      if (it_evl != evl.end()) {
+        for ( ; it_evl != evl.end() ; ++it_evl) {
+          save << " " << (*it_evl)[0];
+          save << " " << (*it_evl)[1];
+          save << " " << (*it_evl)[2];
+          save << "$"; // "$" is a mark of enforced vertex end
+        }
+      }
+      save << "#"; // "#" is a mark of enforced shape end
+    }
+    save << " " << "__ENFORCED_VERTICES_END__";
+  }
+
   return save;
 }
 
@@ -513,31 +734,31 @@ std::istream & BLSURFPlugin_Hypothesis::LoadFrom(std::istream & load)
     _phyMin = val;
   else
     load.clear(std::ios::badbit | load.rdstate());
-  
+
   isOK = (load >> val);
   if (isOK)
     _phyMax = val;
   else
     load.clear(std::ios::badbit | load.rdstate());
-  
+
   isOK = (load >> val);
   if (isOK)
     _angleMeshC = val;
   else
     load.clear(std::ios::badbit | load.rdstate());
-  
+
   isOK = (load >> val);
   if (isOK)
     _hgeoMin = val;
   else
     load.clear(std::ios::badbit | load.rdstate());
-  
+
   isOK = (load >> val);
   if (isOK)
     _hgeoMax = val;
   else
     load.clear(std::ios::badbit | load.rdstate());
-  
+
   isOK = (load >> i);
   if (isOK)
     _verb = i;
@@ -548,6 +769,7 @@ std::istream & BLSURFPlugin_Hypothesis::LoadFrom(std::istream & load)
   bool hasOptions = false;
   bool hasSizeMap = false;
   bool hasAttractor = false;
+  bool hasEnforcedVertex = false;
 
   isOK = (load >> option_or_sm);
   if (isOK)
@@ -557,6 +779,8 @@ std::istream & BLSURFPlugin_Hypothesis::LoadFrom(std::istream & load)
       hasSizeMap = true;
     else if (option_or_sm == "__ATTRACTORS_BEGIN__")
       hasAttractor = true;
+    else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
+      hasEnforcedVertex = true;
 
   std::string optName, optValue;
   while (isOK && hasOptions) {
@@ -594,6 +818,8 @@ std::istream & BLSURFPlugin_Hypothesis::LoadFrom(std::istream & load)
         hasSizeMap = true;
       else if (option_or_sm == "__ATTRACTORS_BEGIN__")
         hasAttractor = true;
+      else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
+        hasEnforcedVertex = true;
   }
 
   std::string smEntry, smValue;
@@ -627,8 +853,11 @@ std::istream & BLSURFPlugin_Hypothesis::LoadFrom(std::istream & load)
 
   if (hasSizeMap) {
     isOK = (load >> option_or_sm);
-    if (isOK && option_or_sm == "__ATTRACTORS_BEGIN__")
-      hasAttractor = true;
+    if (isOK)
+      if (option_or_sm == "__ATTRACTORS_BEGIN__")
+        hasAttractor = true;
+      else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
+        hasEnforcedVertex = true;
   }
 
   std::string atEntry, atValue;
@@ -659,6 +888,67 @@ std::istream & BLSURFPlugin_Hypothesis::LoadFrom(std::istream & load)
       value3[ len3-2 ] = '\0'; //cut off "%#"
     }
   }
+  
+  if (hasAttractor) {
+    isOK = (load >> option_or_sm);
+    if (isOK)
+      if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
+        hasEnforcedVertex = true;
+  }
+  
+  std::string enfEntry, enfValue, trace;
+  std::ostringstream oss;
+  while (isOK && hasEnforcedVertex) {
+    isOK = (load >> enfEntry);
+    if (isOK) {
+      if (enfEntry == "__ENFORCED_VERTICES_END__")
+        break;
+
+      enfValue = "begin";
+      int len4 = enfValue.size();
+
+      TEnforcedVertexList & evl = _enforcedVertices[enfEntry];
+      evl.clear();
+      TEnforcedVertex enfVertex;
+
+      // continue reading until "#" encountered
+      while ( enfValue[len4-1] != '#') {
+        // New vector begin
+        enfVertex.clear();
+        while ( enfValue[len4-1] != '$') {
+          isOK = (load >> enfValue);
+          if (isOK) {
+            len4 = enfValue.size();
+            // End of vertex list
+            if (enfValue[len4-1] == '#')
+              break;
+            if (enfValue[len4-1] != '$') {
+              // Add to vertex
+              enfVertex.push_back(atof(enfValue.c_str()));
+            }
+          }
+          else
+            break;
+        }
+        if (enfValue[len4-1] == '$') {
+          // Remove '$' and add to vertex
+          enfValue[len4-1] = '\0'; //cut off "$#"
+          enfVertex.push_back(atof(enfValue.c_str()));
+          // Add vertex to list of vertex
+          evl.insert(enfVertex);
+        }
+      }
+      if (enfValue[len4-1] == '#') {
+        // Remove '$#' and add to vertex
+        enfValue[len4-2] = '\0'; //cut off "$#"
+        enfVertex.push_back(atof(enfValue.c_str()));
+        // Add vertex to list of vertex
+        evl.insert(enfVertex);
+      }
+    }
+    else
+      break;
+  }
 
   return load;
 }
index de5af169f83168846dc585318dd0637646b8c869..8586dec0a39f642a1c68eb816203e5180d4279d1 100644 (file)
@@ -27,6 +27,7 @@
 #define _BLSURFPlugin_Hypothesis_HXX_
 
 #include "SMESH_Hypothesis.hxx"
+#include <vector>
 #include <map>
 #include <set>
 #include <stdexcept>
@@ -98,18 +99,26 @@ public:
   int GetVerbosity() const { return _verb; }
   
   void ClearEntry(const std::string& entry);
-  void ClearSizeMaps();  
+  void ClearSizeMaps();
 
   typedef std::map<std::string,std::string> TSizeMap;
 
   void SetSizeMapEntry(const std::string& entry,const std::string& sizeMap );
   std::string  GetSizeMapEntry(const std::string& entry);
-  const TSizeMap& GetSizeMapEntries() const { return _sizeMap; }  
+  const TSizeMap& _GetSizeMapEntries() const { return _sizeMap; }
+  /*!
+   * \brief Return the size maps
+   */
+  static TSizeMap GetSizeMapEntries(const BLSURFPlugin_Hypothesis* hyp);
 
 
   void SetAttractorEntry(const std::string& entry,const std::string& attractor );
   std::string GetAttractorEntry(const std::string& entry);
-  const TSizeMap& GetAttractorEntries() const { return _attractors; };
+  const TSizeMap& _GetAttractorEntries() const { return _attractors; };
+  /*!
+   * \brief Return the attractors
+   */
+  static TSizeMap GetAttractorEntries(const BLSURFPlugin_Hypothesis* hyp);
 
 
 /*
@@ -119,18 +128,43 @@ public:
   const TSizeMap& GetCustomSizeMapEntries() const { return _customSizeMap; }
  */
 
-  static Topology      GetDefaultTopology();
-  static PhysicalMesh  GetDefaultPhysicalMesh();
-  static double        GetDefaultPhySize();
-  static double        GetDefaultMaxSize();
-  static double        GetDefaultMinSize();
-  static GeometricMesh GetDefaultGeometricMesh();
-  static double        GetDefaultAngleMeshS();
-  static double        GetDefaultAngleMeshC() { return GetDefaultAngleMeshS(); }
-  static double        GetDefaultGradation();
-  static bool          GetDefaultQuadAllowed();
-  static bool          GetDefaultDecimesh();
-  static int           GetDefaultVerbosity() { return 10; }
+  /*!
+   * To set/get/unset an enforced vertex
+   */
+  typedef std::vector<double> TEnforcedVertex;
+  typedef std::set< TEnforcedVertex > TEnforcedVertexList;
+  typedef std::map< std::string, TEnforcedVertexList > TEnforcedVertexMap;
+  
+  void SetEnforcedVertex(const std::string& entry, double x, double y, double z);
+//   void SetEnforcedVertexList(const std::string& entry, const TEnforcedVertexList vertexList);
+  TEnforcedVertexList GetEnforcedVertices(const std::string& entry) throw (std::invalid_argument);
+  void ClearEnforcedVertex(const std::string& entry, double x, double y, double z) throw (std::invalid_argument);
+//   void ClearEnforcedVertexList(const std::string& entry, TEnforcedVertexList vertexList) throw (std::invalid_argument);
+  void ClearEnforcedVertices(const std::string& entry) throw (std::invalid_argument);
+
+  void ClearAllEnforcedVertices();
+  const TEnforcedVertexMap _GetAllEnforcedVertices() const { return _enforcedVertices; }
+
+  /*!
+   * \brief Return the enforced vertices
+   */
+  static TEnforcedVertexMap GetAllEnforcedVertices(const BLSURFPlugin_Hypothesis* hyp);
+
+
+  static Topology        GetDefaultTopology();
+  static PhysicalMesh    GetDefaultPhysicalMesh();
+  static double          GetDefaultPhySize();
+  static double          GetDefaultMaxSize();
+  static double          GetDefaultMinSize();
+  static GeometricMesh   GetDefaultGeometricMesh();
+  static double          GetDefaultAngleMeshS();
+  static double          GetDefaultAngleMeshC() { return GetDefaultAngleMeshS(); }
+  static double          GetDefaultGradation();
+  static bool            GetDefaultQuadAllowed();
+  static bool            GetDefaultDecimesh();
+  static int             GetDefaultVerbosity() { return 10; }
+  static TSizeMap        GetDefaultSizeMap() { return TSizeMap();}
+  static TEnforcedVertexMap GetDefaultEnforcedVertexMap() { return TEnforcedVertexMap(); }
 
   static double undefinedDouble() { return -1.0; }
 
@@ -164,19 +198,20 @@ public:
   virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0);
 
 private:
-  Topology      _topology;
-  PhysicalMesh  _physicalMesh;
-  double        _phySize, _phyMin, _phyMax;
-  GeometricMesh _geometricMesh;
-  double        _angleMeshS, _angleMeshC, _hgeoMin, _hgeoMax;
-  double        _gradation;
-  bool          _quadAllowed;
-  bool          _decimesh;
-  int           _verb;
-  TOptionValues _option2value;
-  TOptionNames  _doubleOptions, _charOptions;
-  TSizeMap      _sizeMap;
-  TSizeMap      _attractors;
+  Topology        _topology;
+  PhysicalMesh    _physicalMesh;
+  double          _phySize, _phyMin, _phyMax;
+  GeometricMesh   _geometricMesh;
+  double          _angleMeshS, _angleMeshC, _hgeoMin, _hgeoMax;
+  double          _gradation;
+  bool            _quadAllowed;
+  bool            _decimesh;
+  int             _verb;
+  TOptionValues   _option2value;
+  TOptionNames    _doubleOptions, _charOptions;
+  TSizeMap        _sizeMap;
+  TSizeMap        _attractors;
+  TEnforcedVertexMap _enforcedVertices;
 /*
   TSizeMap      _customSizeMap;
 */
index 815ea9db9cffbecd4ed650871981b71cbb8b28f4..56d49f54404886b6298010a8f9ecd658cbfc7cbd 100644 (file)
@@ -31,6 +31,7 @@
 #include "utilities.h"
 
 #include <stdexcept>
+#include "boost/regex.hpp"
 
 //=============================================================================
 /*!
@@ -549,8 +550,12 @@ void BLSURFPlugin_Hypothesis_i::SetAttractorEntry(const char* entry,const char*
   bool valueChanged = false;
   try {
     valueChanged = ( this->GetImpl()->GetAttractorEntry(entry) != attractor );
-    if ( valueChanged )
+    if ( valueChanged ) {
+      boost::regex re("^ATTRACTOR\\((?:(-?0(\\.\\d*)*|-?[1-9]+\\d*(\\.\\d*)*|-?\\.(\\d)+);){5}(True|False)\\)$");
+      if (!boost::regex_match(string(attractor), re))
+        throw std::invalid_argument("Error: an attractor is defined with the following pattern: ATTRACTOR(xa;ya;za;a;b;True|False)");
       this->GetImpl()->SetAttractorEntry(entry, attractor);
+    }
   }
   catch (const std::invalid_argument& ex) {
     SALOME::ExceptionStruct ExDescription;
@@ -571,7 +576,7 @@ void BLSURFPlugin_Hypothesis_i::SetAttractorEntry(const char* entry,const char*
 
 
 //=============================================================================
-                                                             
+
 char* BLSURFPlugin_Hypothesis_i::GetSizeMapEntry(const char* entry) 
   throw (SALOME::SALOME_Exception)
 {
@@ -632,7 +637,7 @@ BLSURFPlugin::string_array* BLSURFPlugin_Hypothesis_i::GetSizeMapEntries()
   ASSERT(myBaseImpl);
   BLSURFPlugin::string_array_var result = new BLSURFPlugin::string_array();
 
-  const ::BLSURFPlugin_Hypothesis::TSizeMap & sizeMaps= this->GetImpl()->GetSizeMapEntries();
+  const ::BLSURFPlugin_Hypothesis::TSizeMap sizeMaps= this->GetImpl()->_GetSizeMapEntries();
   result->length( sizeMaps.size() );
 
   ::BLSURFPlugin_Hypothesis::TSizeMap::const_iterator smIt = sizeMaps.begin();
@@ -647,14 +652,14 @@ BLSURFPlugin::string_array* BLSURFPlugin_Hypothesis_i::GetSizeMapEntries()
   return result._retn();
 }
 
-//=============================================================================                   
+//=============================================================================
 
 BLSURFPlugin::string_array* BLSURFPlugin_Hypothesis_i::GetAttractorEntries()
 {
   ASSERT(myBaseImpl);
   BLSURFPlugin::string_array_var result = new BLSURFPlugin::string_array();
 
-  const ::BLSURFPlugin_Hypothesis::TSizeMap & attractors= this->GetImpl()->GetAttractorEntries();
+  const ::BLSURFPlugin_Hypothesis::TSizeMap attractors= this->GetImpl()->_GetAttractorEntries();
   result->length( attractors.size() );
 
   ::BLSURFPlugin_Hypothesis::TSizeMap::const_iterator atIt = attractors.begin();
@@ -669,27 +674,27 @@ BLSURFPlugin::string_array* BLSURFPlugin_Hypothesis_i::GetAttractorEntries()
   return result._retn();
 }
 
-//=============================================================================                   
-                                                                                                  
-void BLSURFPlugin_Hypothesis_i::SetSizeMapEntries(const BLSURFPlugin::string_array& sizeMaps)        
-  throw (SALOME::SALOME_Exception)                                                                
-{                                                                                                 
-  ASSERT(myBaseImpl);                                                                             
-  for (int i = 0; i < sizeMaps.length(); ++i)                                                      
-  {                                                                                               
-    string entry_sizemap = sizeMaps[i].in();                                                          
-    int colonPos = entry_sizemap.find( '|' );                                                        
-    string entry, sizemap;                                                                           
-    if ( colonPos == string::npos ) // '|' separator not found                                              
-      entry = entry_sizemap;                                                                          
-    else {                                                                                        
-      entry = entry_sizemap.substr( 0, colonPos);                                                     
-      if ( colonPos < entry_sizemap.size()-1 && entry_sizemap[colonPos] != ' ')                         
-        sizemap = entry_sizemap.substr( colonPos+1 );                                                  
-    }                                                                                             
-    this->GetImpl()->SetSizeMapEntry( entry.c_str(), sizemap.c_str() );                                                
-  }                                                                                               
-}                                                                                                 
+//=============================================================================
+
+void BLSURFPlugin_Hypothesis_i::SetSizeMapEntries(const BLSURFPlugin::string_array& sizeMaps)
+  throw (SALOME::SALOME_Exception)
+{
+  ASSERT(myBaseImpl);
+  for (int i = 0; i < sizeMaps.length(); ++i)
+  {
+    string entry_sizemap = sizeMaps[i].in();
+    int colonPos = entry_sizemap.find( '|' );
+    string entry, sizemap;
+    if ( colonPos == string::npos ) // '|' separator not found
+      entry = entry_sizemap;
+    else {
+      entry = entry_sizemap.substr( 0, colonPos);
+      if ( colonPos < entry_sizemap.size()-1 && entry_sizemap[colonPos] != ' ')
+        sizemap = entry_sizemap.substr( colonPos+1 );
+    }
+    this->GetImpl()->SetSizeMapEntry( entry.c_str(), sizemap.c_str() );
+  }
+}
 
 //=============================================================================
 
@@ -775,7 +780,287 @@ BLSURFPlugin::string_array* BLSURFPlugin_Hypothesis_i::GetCustomSizeMapEntries()
 
 */
 
-     
+
+///////////////////////
+// ENFORCED VERTEXES //
+///////////////////////
+
+BLSURFPlugin::TEnforcedVertexMap* BLSURFPlugin_Hypothesis_i::GetAllEnforcedVertices()
+{
+  MESSAGE("IDL: GetAllEnforcedVertices()");
+  ASSERT(myBaseImpl);
+  BLSURFPlugin::TEnforcedVertexMap_var resultMap = new BLSURFPlugin::TEnforcedVertexMap();
+  const ::BLSURFPlugin_Hypothesis::TEnforcedVertexMap enforcedVertexMap = this->GetImpl()->_GetAllEnforcedVertices();
+  resultMap->length(enforcedVertexMap.size());
+  MESSAGE("Enforced Vertex map size is " << enforcedVertexMap.size());
+
+  ::BLSURFPlugin_Hypothesis::TEnforcedVertexList enforcedVertexList;
+  ::BLSURFPlugin_Hypothesis::TEnforcedVertexMap::const_iterator evmIt = enforcedVertexMap.begin();
+  for ( int i = 0 ; evmIt != enforcedVertexMap.end(); ++evmIt, ++i ) {
+    string entry = evmIt->first;
+    MESSAGE("Entry: " << entry);
+    enforcedVertexList = evmIt->second;
+
+    BLSURFPlugin::TEnforcedVertexMapElement_var mapElement = new BLSURFPlugin::TEnforcedVertexMapElement();
+
+    BLSURFPlugin::TEnforcedVertexList_var vertexList = new BLSURFPlugin::TEnforcedVertexList();
+    vertexList->length(enforcedVertexList.size());
+    MESSAGE("Number of enforced vertices: " << enforcedVertexList.size());
+
+    ::BLSURFPlugin_Hypothesis::TEnforcedVertexList::const_iterator evlIt = enforcedVertexList.begin();
+    for ( int j = 0 ; evlIt != enforcedVertexList.end(); ++evlIt, ++j ) {
+      MESSAGE("Enforced Vertex #" << j);
+      BLSURFPlugin::TEnforcedVertex_var enforcedVertex = new BLSURFPlugin::TEnforcedVertex();
+      enforcedVertex->length(3);
+      enforcedVertex[0] = (*evlIt)[0];
+      enforcedVertex[1] = (*evlIt)[1];
+      enforcedVertex[2] = (*evlIt)[2];
+      vertexList[j] = enforcedVertex;
+      MESSAGE("Enforced vertex: " << enforcedVertex[0] << ", " << enforcedVertex[1] << ", " << enforcedVertex[2]);
+    }
+
+    mapElement->entry = CORBA::string_dup(entry.c_str());
+    mapElement->vertexList = vertexList;
+
+    resultMap[i] = mapElement;
+
+  }
+  return resultMap._retn();
+}
+
+void BLSURFPlugin_Hypothesis_i::ClearAllEnforcedVertices()
+{
+  ASSERT(myBaseImpl);
+  this->GetImpl()->ClearAllEnforcedVertices();
+  SMESH::TPythonDump() << _this() << ".ClearAllEnforcedVertices()";
+}
+
+/*!
+  * Set/get/unset an enforced vertex on geom object
+  */
+void BLSURFPlugin_Hypothesis_i::SetEnforcedVertex(GEOM::GEOM_Object_ptr GeomObj, CORBA::Double x, CORBA::Double y, CORBA::Double z)
+  throw (SALOME::SALOME_Exception)
+{
+  ASSERT(myBaseImpl);
+  // TODO check that GeomObj is a face => in engine ?
+  string entry = GeomObj->GetStudyEntry();
+  MESSAGE("IDL : GetName : " << GeomObj->GetName());
+  MESSAGE("IDL : SetEnforcedVertex ( "<< entry << ", " << x << ", " << y << ", " << z << ")");
+  try {
+    SetEnforcedVertexEntry(entry.c_str(), x, y, z);
+  }
+  catch (SALOME_Exception& ex) {
+    THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM );
+  }
+}
+
+
+BLSURFPlugin::TEnforcedVertexList* BLSURFPlugin_Hypothesis_i::GetEnforcedVertices(GEOM::GEOM_Object_ptr GeomObj)
+  throw (SALOME::SALOME_Exception)
+{
+  ASSERT(myBaseImpl);
+  string entry = GeomObj->GetStudyEntry();
+  MESSAGE("IDL : GetName : " << GeomObj->GetName());
+  MESSAGE("IDL : GetEnforcedVertexList ( "<< entry << ")");
+  try {
+    return GetEnforcedVerticesEntry(entry.c_str());
+  }
+  catch (SALOME_Exception& ex) {
+    THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM );
+  }
+}
+
+
+void BLSURFPlugin_Hypothesis_i::UnsetEnforcedVertex(GEOM::GEOM_Object_ptr GeomObj, CORBA::Double x, CORBA::Double y, CORBA::Double z)
+  throw (SALOME::SALOME_Exception)
+{
+  ASSERT(myBaseImpl);
+  string entry = GeomObj->GetStudyEntry();
+  MESSAGE("IDL : GetName : " << GeomObj->GetName());
+  MESSAGE("IDL : UnsetEnforcedVertex ( "<< entry << ", " << x << ", " << y << ", " << z << ")");
+
+  try {
+    UnsetEnforcedVertexEntry(entry.c_str(), x, y, z);
+  }
+  catch (SALOME_Exception& ex) {
+    THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM );
+  }
+}
+
+
+void BLSURFPlugin_Hypothesis_i::UnsetEnforcedVertices(GEOM::GEOM_Object_ptr GeomObj)
+  throw (SALOME::SALOME_Exception)
+{
+  ASSERT(myBaseImpl);;
+  string entry = GeomObj->GetStudyEntry();
+  MESSAGE("IDL : GetName : " << GeomObj->GetName());
+  MESSAGE("IDL : UnsetEnforcedVertices ( "<< entry << ")");
+
+  try {
+    UnsetEnforcedVerticesEntry(entry.c_str());
+  }
+  catch (SALOME_Exception& ex) {
+    THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM );
+  }
+}
+
+
+/*!
+  * Set/get/unset an enforced vertex on geom object given by entry
+  */
+void BLSURFPlugin_Hypothesis_i::SetEnforcedVertexEntry(const char* entry, double x, double y, double z)
+  throw (SALOME::SALOME_Exception)
+{
+  ASSERT(myBaseImpl);
+  MESSAGE("IDL : SETENFORCEDVERTEX START - ENTRY: " << entry << " VERTEX: " << x << " " << y << " " << z);
+  bool newValue = false;
+  
+  try {
+    ::BLSURFPlugin_Hypothesis::TEnforcedVertexList vertexList = this->GetImpl()->GetEnforcedVertices(entry);
+    ::BLSURFPlugin_Hypothesis::TEnforcedVertex vertex;
+    vertex.push_back(x);
+    vertex.push_back(y);
+    vertex.push_back(z);
+    if (vertexList.find(vertex) == vertexList.end()) {
+      MESSAGE("Vertex not found: add it in vertexList")
+      newValue = true;
+    }
+    else
+      MESSAGE("Vertex already found")
+  }
+  catch (const std::invalid_argument& ex) {
+    // no enforced vertex for entry
+    MESSAGE("Entry not found : add it to the list")
+    newValue = true;
+  }
+  catch (SALOME_Exception& ex) {
+    THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM );
+  }
+  
+  if ( newValue ) {
+    this->GetImpl()->SetEnforcedVertex(entry, x, y, z);
+    SMESH::TPythonDump() << _this() << ".SetEnforcedVertex("
+                         << entry << ", "
+                         << x << ", "
+                         << y << ", "
+                         << z << ")";
+  }
+  MESSAGE("IDL : SETENFORCEDVERTEX END - ENTRY: " << entry);
+}
+/*
+void BLSURFPlugin_Hypothesis_i::SetEnforcedVertexListEntry(const char* entry, BLSURFPlugin::TEnforcedVertexList& vertexList)
+  throw (SALOME::SALOME_Exception)
+{
+  ASSERT(myBaseImpl);
+}
+*/
+
+BLSURFPlugin::TEnforcedVertexList* BLSURFPlugin_Hypothesis_i::GetEnforcedVerticesEntry(const char* entry)
+  throw (SALOME::SALOME_Exception)
+{
+  ASSERT(myBaseImpl);
+  MESSAGE("ENGINE : GETENFORCEDVERTICES START ENTRY : " << entry);
+  
+  try {
+    BLSURFPlugin::TEnforcedVertexList_var vertexList = new BLSURFPlugin::TEnforcedVertexList();
+    ::BLSURFPlugin_Hypothesis::TEnforcedVertexList _vList = this->GetImpl()->GetEnforcedVertices(entry);
+    vertexList->length(_vList.size());
+    MESSAGE("Number of enforced vertices: " << _vList.size());
+    ::BLSURFPlugin_Hypothesis::TEnforcedVertexList::const_iterator evlIt = _vList.begin();
+    for ( int i = 0; evlIt != _vList.end() ; ++evlIt, ++i ) {
+      BLSURFPlugin::TEnforcedVertex_var enforcedVertex = new BLSURFPlugin::TEnforcedVertex();
+      enforcedVertex->length(3);
+      MESSAGE("Enforced vertex #" << i << ": "<< (*evlIt)[0] << ", " << (*evlIt)[1] << ", " << (*evlIt)[2]);
+      enforcedVertex[0] = (*evlIt)[0];
+      enforcedVertex[1] = (*evlIt)[1];
+      enforcedVertex[2] = (*evlIt)[2];
+      vertexList[i] = enforcedVertex;
+    }
+    return vertexList._retn();
+  }
+  catch (const std::invalid_argument& ex) {
+    SALOME::ExceptionStruct ExDescription;
+    ExDescription.text = ex.what();
+    ExDescription.type = SALOME::BAD_PARAM;
+    ExDescription.sourceFile = "BLSURFPlugin_Hypothesis_i::GetEnforcedVerticesEntry(entry)";
+    ExDescription.lineNumber = 945;
+    throw SALOME::SALOME_Exception(ExDescription);
+  }
+  catch(const std::exception& ex) {
+    THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM );
+  }
+
+  MESSAGE("ENGINE : GETENFORCEDVERTICES END ENTRY : " << entry);
+}
+
+
+void BLSURFPlugin_Hypothesis_i::UnsetEnforcedVertexEntry(const char* entry, CORBA::Double x, CORBA::Double y, CORBA::Double z)
+  throw (SALOME::SALOME_Exception)
+{
+  ASSERT(myBaseImpl);
+  MESSAGE("ENGINE : UNSETENFORCEDVERTEX START ENTRY : " << entry);
+  
+  try {
+    this->GetImpl()->ClearEnforcedVertex(entry, x, y, z);
+    SMESH::TPythonDump() << _this() << ".UnsetEnforcedVertex("
+                         << entry << ", "
+                         << x << ", "
+                         << y << ", "
+                         << z << ")";
+  }
+  catch (const std::invalid_argument& ex) {
+    SALOME::ExceptionStruct ExDescription;
+    ExDescription.text = ex.what();
+    ExDescription.type = SALOME::BAD_PARAM;
+    ExDescription.sourceFile = "BLSURFPlugin_Hypothesis_i::UnsetEnforcedVertexEntry(entry,x,y,z)";
+    ExDescription.lineNumber = 1003;
+    throw SALOME::SALOME_Exception(ExDescription);
+  }
+  catch(const std::exception& ex) {
+    THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM );
+  }
+
+  MESSAGE("ENGINE : UNSETENFORCEDVERTEX END ENTRY : " << entry);
+}
+/*
+void BLSURFPlugin_Hypothesis_i::UnsetEnforcedVertexListEntry(const char* entry, BLSURFPlugin::TEnforcedVertexList& vertexList)
+  throw (SALOME::SALOME_Exception)
+{
+  ASSERT(myBaseImpl);
+}
+*/
+void BLSURFPlugin_Hypothesis_i::UnsetEnforcedVerticesEntry(const char* entry)
+  throw (SALOME::SALOME_Exception)
+{
+  ASSERT(myBaseImpl);
+  MESSAGE("ENGINE : UNSETENFORCEDVERTICES START ENTRY : " << entry);
+  
+  try {
+    this->GetImpl()->ClearEnforcedVertices(entry);
+    SMESH::TPythonDump() << _this() << ".UnsetEnforcedVertices(" << entry << ")";
+  }
+  catch (const std::invalid_argument& ex) {
+    SALOME::ExceptionStruct ExDescription;
+    ExDescription.text = ex.what();
+    ExDescription.type = SALOME::BAD_PARAM;
+    ExDescription.sourceFile = "BLSURFPlugin_Hypothesis_i::UnsetEnforcedVerticesEntry(entry)";
+    ExDescription.lineNumber = 1051;
+    throw SALOME::SALOME_Exception(ExDescription);
+  }
+  catch(const std::exception& ex) {
+    THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM );
+  }
+
+  MESSAGE("ENGINE : UNSETENFORCEDVERTICES END ENTRY : " << entry);
+}
+
+
+///////////////////////
+
+
+
+
+
 //=============================================================================
 /*!
  *  BLSURFPlugin_Hypothesis_i::GetImpl
index eef96171d292c34f8d1f680d83e1de7203fa2354..fef59b7298f4a245308ebb0e1701443c826c03ec 100644 (file)
@@ -140,9 +140,37 @@ class BLSURFPlugin_Hypothesis_i:
   BLSURFPlugin::string_array* GetCustomSizeMapEntries();
 */
 
+  ///////////////////////
+  // ENFORCED VERTEXES //
+  ///////////////////////
+  
+  BLSURFPlugin::TEnforcedVertexMap* GetAllEnforcedVertices();
+  void                              ClearAllEnforcedVertices();
+
+  /*!
+    * Set/get/unset an enforced vertex on geom object
+    */
+  void         SetEnforcedVertex(GEOM::GEOM_Object_ptr GeomObj, CORBA::Double x, CORBA::Double y, CORBA::Double z) throw (SALOME::SALOME_Exception);
+//   void         SetEnforcedVertexList(GEOM::GEOM_Object_ptr GeomObj, const BLSURFPlugin::TEnforcedVertexList& vertexList) throw (SALOME::SALOME_Exception);
+  BLSURFPlugin::TEnforcedVertexList* GetEnforcedVertices(GEOM::GEOM_Object_ptr GeomObj) throw (SALOME::SALOME_Exception);
+  void         UnsetEnforcedVertex(GEOM::GEOM_Object_ptr GeomObj, CORBA::Double x, CORBA::Double y, CORBA::Double z) throw (SALOME::SALOME_Exception);
+//   void         UnsetEnforcedVertexList(GEOM::GEOM_Object_ptr GeomObj, BLSURFPlugin::TEnforcedVertexList& vertexList) throw (SALOME::SALOME_Exception);
+  void         UnsetEnforcedVertices(GEOM::GEOM_Object_ptr GeomObj) throw (SALOME::SALOME_Exception);
+
+  /*!
+    * Set/get/unset an enforced vertex on geom object given by entry
+    */
+  void         SetEnforcedVertexEntry(const char* entry, double x, double y, double z) throw (SALOME::SALOME_Exception);
+//   void         SetEnforcedVertexListEntry(const char* entry, BLSURFPlugin::TEnforcedVertexList& vertexList) throw (SALOME::SALOME_Exception);
+  BLSURFPlugin::TEnforcedVertexList* GetEnforcedVerticesEntry(const char* entry) throw (SALOME::SALOME_Exception);
+  void         UnsetEnforcedVertexEntry(const char* entry, CORBA::Double x, CORBA::Double y, CORBA::Double z) throw (SALOME::SALOME_Exception);
+//   void         UnsetEnforcedVertexListEntry(const char* entry, BLSURFPlugin::TEnforcedVertexList& vertexList) throw (SALOME::SALOME_Exception);
+  void         UnsetEnforcedVerticesEntry(const char* entry) throw (SALOME::SALOME_Exception);
+  ///////////////////////
+
   // Get implementation
   ::BLSURFPlugin_Hypothesis* GetImpl();
-  
+
   // Verify whether hypothesis supports given entity type 
   CORBA::Boolean IsDimSupported( SMESH::Dimension type );
 };
index 209aa9cb3b2a8272ed72400f45d0845b51960989..1e7dda08336af277bc8b7ef1eb9b18dbe32c3785 100644 (file)
@@ -65,3 +65,4 @@ libBLSURFEngine_la_LDFLAGS  =                 \
        $(SMESH_LDFLAGS) -lSMESHimpl -lSMESHEngine -lStdMeshersEngine -lSMDS -lSMESHDS  \
        $(GEOM_LDFLAGS) -lGEOMbasic \
        $(KERNEL_LDFLAGS) -lSalomeGenericObj -lSalomeNS -lSALOMELocalTrace
+       $(BOOST_LIB_REGEX)
index c86ce905c2c1ce166b2aea2324b25559f96e37bd..bf3001326cd451a2ad1d67f9ee7754b37d0df445 100644 (file)
 #include <SUIT_MessageBox.h>
 #include <SUIT_ResourceMgr.h>
 #include <SalomeApp_Tools.h>
-#include <QtxDoubleSpinBox.h>
+#include <SalomeApp_DoubleSpinBox.h>
 
 #include <QComboBox>
 #include <QLabel>
 #include <QGroupBox>
 #include <QFrame>
 #include <QVBoxLayout>
+#include <QHBoxLayout>
 #include <QGridLayout>
 #include <QLineEdit>
 #include <QCheckBox>
 #include <QApplication>
 #include <QRadioButton>
 
+#include <QStandardItemModel>
+#include <QStandardItem>
+#include <QTreeWidget>
+#include <QTreeWidgetItem>
+#include <QModelIndexList>
+
 #include <LightApp_SelectionMgr.h>
 #include <SalomeApp_Application.h>
 #include <SALOME_ListIO.hxx>
@@ -89,6 +96,7 @@ enum {
   STD_TAB = 0,
   ADV_TAB,
   SMP_TAB,
+  ENF_TAB,
   OPTION_ID_COLUMN = 0,
   OPTION_NAME_COLUMN,
   OPTION_VALUE_COLUMN,
@@ -110,6 +118,28 @@ enum {
   SMP_REMOVE_BTN,
 };
 
+// Enforced vertices inputs
+enum {
+  ENF_VER_BTNS = 0,
+  ENF_VER_X_COORD = 0,
+  ENF_VER_Y_COORD,
+  ENF_VER_Z_COORD,
+  ENF_VER_VERTEX_BTN,
+  ENF_VER_SEPARATOR,
+  ENF_VER_REMOVE_BTN,
+};
+
+// Enforced vertices array columns
+enum {
+  ENF_VER_NAME_COLUMN = 0,
+  ENF_VER_ENTRY_COLUMN,
+  ENF_VER_X_COLUMN,
+  ENF_VER_Y_COLUMN,
+  ENF_VER_Z_COLUMN,
+  ENF_VER_NB_COLUMNS
+};
+
+
 /**************************************************
  Begin initialization Python structures and objects
 ***************************************************/
@@ -216,6 +246,134 @@ PyObject * newPyStdOut( std::string& out )
 End initialization Python structures and objects
 **************************************************/
 
+
+class QDoubleValidator;
+
+//
+// BEGIN EnforcedTreeWidgetDelegate
+//
+
+EnforcedTreeWidgetDelegate::EnforcedTreeWidgetDelegate(QObject *parent)
+  : QItemDelegate(parent)
+{
+}
+
+QWidget *EnforcedTreeWidgetDelegate::createEditor(QWidget *parent,
+                                              const QStyleOptionViewItem & option ,
+                                              const QModelIndex & index ) const
+{
+  QLineEdit *editor = new QLineEdit(parent);
+  if (index.column() == ENF_VER_X_COLUMN || \
+    index.column() == ENF_VER_Y_COLUMN || \
+    index.column() == ENF_VER_Z_COLUMN)
+    editor->setValidator(new QDoubleValidator(parent));
+
+  return editor;
+}
+
+void EnforcedTreeWidgetDelegate::setEditorData(QWidget *editor,
+                                           const QModelIndex &index) const
+{
+  QString value = index.model()->data(index, Qt::EditRole).toString();
+
+  QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
+  lineEdit->setText(value);
+}
+
+void EnforcedTreeWidgetDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
+                                          const QModelIndex &index) const
+{
+  QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
+
+  if (index.column() == ENF_VER_X_COLUMN || \
+    index.column() == ENF_VER_Y_COLUMN || \
+    index.column() == ENF_VER_Z_COLUMN)
+  {
+    if (not vertexExists(model, index, lineEdit->text())) {
+      bool ok;
+      double value = lineEdit->text().toDouble(&ok);
+      if (ok)
+        model->setData(index, value, Qt::EditRole);
+    }
+  }
+  else if (index.column() == ENF_VER_NAME_COLUMN) {
+    QString value = lineEdit->text();
+    if (not vertexExists(model, index, value))
+      model->setData(index, value, Qt::EditRole);
+//     MESSAGE("Value " << value.toString().toStdString() << " was set at index(" << index.row() << "," << index.column() << ")");
+  }
+}
+
+void EnforcedTreeWidgetDelegate::updateEditorGeometry(QWidget *editor,
+    const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
+{
+  editor->setGeometry(option.rect);
+}
+
+bool EnforcedTreeWidgetDelegate::vertexExists(QAbstractItemModel *model,
+    const QModelIndex &index, QString value) const
+{
+  bool exists = false;
+  QModelIndex parent = index.parent();
+  int row = index.row();
+  int col = index.column();
+  
+  if (parent.isValid()) {
+    if (col == ENF_VER_X_COLUMN || col == ENF_VER_Y_COLUMN || col == ENF_VER_Z_COLUMN) {
+      double x, y, z;
+      if (col == ENF_VER_X_COLUMN) {
+        x = value.toDouble();
+        y = parent.child(row, ENF_VER_Y_COLUMN).data(Qt::EditRole).toDouble();
+        z = parent.child(row, ENF_VER_Z_COLUMN).data(Qt::EditRole).toDouble();
+      }
+      if (col == ENF_VER_Y_COLUMN) {
+        y = value.toDouble();
+        x = parent.child(row, ENF_VER_X_COLUMN).data(Qt::EditRole).toDouble();
+        z = parent.child(row, ENF_VER_Z_COLUMN).data(Qt::EditRole).toDouble();
+      }
+      if (col == ENF_VER_Z_COLUMN) {
+        z = value.toDouble();
+        x = parent.child(row, ENF_VER_X_COLUMN).data(Qt::EditRole).toDouble();
+        y = parent.child(row, ENF_VER_Y_COLUMN).data(Qt::EditRole).toDouble();
+      }
+      // MESSAGE("Checking for existing vertex " << x << ", " << y << "," << z);
+      int nbChildren = model->rowCount(parent);
+      for (int i = 0 ; i < nbChildren ; i++) {
+        if (i != row) {
+          double childX = parent.child(i, ENF_VER_X_COLUMN).data(Qt::EditRole).toDouble();
+          double childY = parent.child(i, ENF_VER_Y_COLUMN).data(Qt::EditRole).toDouble();
+          double childZ = parent.child(i, ENF_VER_Z_COLUMN).data(Qt::EditRole).toDouble();
+//           MESSAGE("Vertex: " << childX << ", " << childY << "," << childZ);
+          if ((childX == x) && (childY == y) && (childZ == z)) {
+//             MESSAGE("Found !");
+            exists = true;
+            break;
+          }
+        }
+      }
+    }
+    else if (index.column() == ENF_VER_NAME_COLUMN) {
+      int nbChildren = model->rowCount(parent);
+      for (int i = 0 ; i < nbChildren ; i++) {
+        if (i != row) {
+          QString childName = parent.child(i, ENF_VER_NAME_COLUMN).data(Qt::EditRole).toString();
+          if (childName == value) {
+            exists = true;
+            break;
+          }
+        }
+      }
+    }
+  }
+
+  return exists;
+}
+
+//
+// END EnforcedTreeWidgetDelegate
+//
+
+
 /**
  * \brief {BLSURFPluginGUI_HypothesisCreator constructor}
  * @param theHypType Name of the hypothesis type (here BLSURF_Parameters)
@@ -246,7 +404,7 @@ BLSURFPluginGUI_HypothesisCreator::BLSURFPluginGUI_HypothesisCreator( const QStr
 
   PyRun_SimpleString("from math import *");
   PyGILState_Release(gstate);
-
+  
 }
 
 BLSURFPluginGUI_HypothesisCreator::~BLSURFPluginGUI_HypothesisCreator()
@@ -258,17 +416,17 @@ BLSURFPluginGUI_HypothesisCreator::~BLSURFPluginGUI_HypothesisCreator()
  * */
 GeomSelectionTools* BLSURFPluginGUI_HypothesisCreator::getGeomSelectionTool()
 {
-  MESSAGE("BLSURFPluginGUI_HypothesisCreator::getGeomSelectionTool");
+//   MESSAGE("BLSURFPluginGUI_HypothesisCreator::getGeomSelectionTool");
   BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
   _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
-  MESSAGE("aStudy->StudyId(): " << aStudy->StudyId());
-  if (that->GeomToolSelected == NULL || that->GeomToolSelected->getMyStudy() != aStudy) {
-    MESSAGE("GeomToolSelected is created");
+//   MESSAGE("aStudy->StudyId(): " << aStudy->StudyId());
+  if (that->GeomToolSelected == NULL or that->GeomToolSelected->getMyStudy() != aStudy) {
+//     MESSAGE("GeomToolSelected is created");
     that->GeomToolSelected = new GeomSelectionTools(aStudy);
   }
-  else
-    MESSAGE("GeomToolSelected already exists");
-  MESSAGE("that->GeomToolSelected->getMyStudy()->StudyId(): " << that->GeomToolSelected->getMyStudy()->StudyId());
+//   else
+//     MESSAGE("GeomToolSelected already exists");
+//   MESSAGE("that->GeomToolSelected->getMyStudy()->StudyId(): " << that->GeomToolSelected->getMyStudy()->StudyId());
   return that->GeomToolSelected;
 }
 
@@ -340,7 +498,7 @@ bool BLSURFPluginGUI_HypothesisCreator::checkParams() const
     h->SetOptionValues( myOptions ); // restore values
   }
 
-  // SizeMap
+  // SizeMap and attractors
   if ( ok )
   {
     mySizeMapTable->setFocus();
@@ -377,6 +535,9 @@ bool BLSURFPluginGUI_HypothesisCreator::checkParams() const
     }
   }
 
+  // Enforced vertices
+  // TODO
+  
   return ok;
 }
 
@@ -408,6 +569,13 @@ QFrame* BLSURFPluginGUI_HypothesisCreator::buildFrame()
     aStdLayout->addWidget( myName, row++, 1, 1, 1 );
   }
 
+  aStdLayout->addWidget( new QLabel( tr( "BLSURF_GRADATION" ), myStdGroup ), row, 0, 1, 1 );
+  myGradation = new SalomeApp_DoubleSpinBox( myStdGroup );
+  aStdLayout->addWidget( myGradation, row++, 1, 1, 1 );
+  myGradation->setMinimum( 1.1 );
+  myGradation->setMaximum( 2.5 );
+  myGradation->setSingleStep( 0.1 );
+
   aStdLayout->addWidget( new QLabel( tr( "BLSURF_PHY_MESH" ), myStdGroup ), row, 0, 1, 1 );
   myPhysicalMesh = new QComboBox( myStdGroup );
   aStdLayout->addWidget( myPhysicalMesh, row++, 1, 1, 1 );
@@ -437,26 +605,19 @@ QFrame* BLSURFPluginGUI_HypothesisCreator::buildFrame()
   myGeometricMesh->addItems( types );
 
   aStdLayout->addWidget( new QLabel( tr( "BLSURF_ANGLE_MESH_S" ), myStdGroup ), row, 0, 1, 1 );
-  myAngleMeshS = new QtxDoubleSpinBox( myStdGroup );
+  myAngleMeshS = new SalomeApp_DoubleSpinBox( myStdGroup );
   aStdLayout->addWidget( myAngleMeshS, row++, 1, 1, 1 );
   myAngleMeshS->setMinimum( 0 );
   myAngleMeshS->setMaximum( 16 );
   myAngleMeshS->setSingleStep( 0.5 );
 
   aStdLayout->addWidget( new QLabel( tr( "BLSURF_ANGLE_MESH_C" ), myStdGroup ), row, 0, 1, 1 );
-  myAngleMeshC = new QtxDoubleSpinBox( myStdGroup );
+  myAngleMeshC = new SalomeApp_DoubleSpinBox( myStdGroup );
   aStdLayout->addWidget( myAngleMeshC, row++, 1, 1, 1 );
   myAngleMeshC->setMinimum( 0 );
   myAngleMeshC->setMaximum( 16 );
   myAngleMeshC->setSingleStep( 0.5 );
 
-  aStdLayout->addWidget( new QLabel( tr( "BLSURF_GRADATION" ), myStdGroup ), row, 0, 1, 1 );
-  myGradation = new QtxDoubleSpinBox( myStdGroup );
-  aStdLayout->addWidget( myGradation, row++, 1, 1, 1 );
-  myGradation->setMinimum( 1.1 );
-  myGradation->setMaximum( 2.5 );
-  myGradation->setSingleStep( 0.1 );
-
 #ifdef WITH_SIZE_BOUNDARIES
   aStdLayout->addWidget( new QLabel( tr( "BLSURF_HGEOMIN" ), myStdGroup ), row, 0, 1, 1 );
   myGeoMin = new QLineEdit( myStdGroup );
@@ -525,6 +686,7 @@ QFrame* BLSURFPluginGUI_HypothesisCreator::buildFrame()
   sizeMapHeaders << tr( "SMP_ENTRY_COLUMN" )<< tr( "SMP_NAME_COLUMN" ) << tr( "SMP_SIZEMAP_COLUMN" );
   mySizeMapTable->setHorizontalHeaderLabels(sizeMapHeaders);
   mySizeMapTable->horizontalHeader()->hideSection( SMP_ENTRY_COLUMN );
+//   mySizeMapTable->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
   mySizeMapTable->resizeColumnToContents(SMP_NAME_COLUMN);
   mySizeMapTable->resizeColumnToContents(SMP_SIZEMAP_COLUMN);
   mySizeMapTable->setAlternatingRowColors(true);
@@ -556,30 +718,300 @@ QFrame* BLSURFPluginGUI_HypothesisCreator::buildFrame()
   removeButton = new QPushButton(tr("BLSURF_SM_REMOVE"),mySmpGroup);
   anSmpLayout->addWidget(removeButton, SMP_REMOVE_BTN, 1, 1, 1);
 
+  // Enforced vertices parameters
+
+  myEnfGroup = new QWidget();
+  QGridLayout* anEnfLayout = new QGridLayout(myEnfGroup);
+
+  myEnforcedTreeWidget = new QTreeWidget(myEnfGroup);
+  myEnforcedTreeWidget->setColumnCount( ENF_VER_NB_COLUMNS );
+  myEnforcedTreeWidget->setSortingEnabled(true);
+  QStringList enforcedHeaders;
+  enforcedHeaders << tr("BLSURF_ENF_VER_NAME_COLUMN") << tr("BLSURF_ENF_VER_ENTRY_COLUMN") << tr( "BLSURF_ENF_VER_X_COLUMN" )<< tr( "BLSURF_ENF_VER_Y_COLUMN" ) << tr( "BLSURF_ENF_VER_Z_COLUMN" ) ;
+  myEnforcedTreeWidget->setHeaderLabels(enforcedHeaders);
+  myEnforcedTreeWidget->setAlternatingRowColors(true);
+  myEnforcedTreeWidget->setUniformRowHeights(true);
+  myEnforcedTreeWidget->setAnimated(true);
+  myEnforcedTreeWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
+  myEnforcedTreeWidget->setSelectionBehavior(QAbstractItemView::SelectItems);
+  for (int column = 0; column < ENF_VER_NB_COLUMNS; ++column) {
+    myEnforcedTreeWidget->header()->setResizeMode(column,QHeaderView::Interactive);
+    myEnforcedTreeWidget->resizeColumnToContents(column);
+  }
+  myEnforcedTreeWidget->hideColumn(ENF_VER_ENTRY_COLUMN);
+  myEnforcedTreeWidget->setItemDelegate(new EnforcedTreeWidgetDelegate());
+  anEnfLayout->addWidget(myEnforcedTreeWidget, 0, 0, 8, 1);
+
+  QLabel* myXCoordLabel = new QLabel( tr( "BLSURF_ENF_VER_X_LABEL" ), myEnfGroup );
+  anEnfLayout->addWidget(myXCoordLabel, ENF_VER_X_COORD, 1, 1, 1);
+  myXCoord = new QLineEdit(myEnfGroup);
+  myXCoord->setValidator(new QDoubleValidator(myEnfGroup));
+  anEnfLayout->addWidget(myXCoord, ENF_VER_X_COORD, 2, 1, 1);
+  
+  QLabel* myYCoordLabel = new QLabel( tr( "BLSURF_ENF_VER_Y_LABEL" ), myEnfGroup );
+  anEnfLayout->addWidget(myYCoordLabel, ENF_VER_Y_COORD, 1, 1, 1);
+  myYCoord = new QLineEdit(myEnfGroup);
+  myYCoord->setValidator(new QDoubleValidator(myEnfGroup));
+  anEnfLayout->addWidget(myYCoord, ENF_VER_Y_COORD, 2, 1, 1);
+  
+  QLabel* myZCoordLabel = new QLabel( tr( "BLSURF_ENF_VER_Z_LABEL" ), myEnfGroup );
+  anEnfLayout->addWidget(myZCoordLabel, ENF_VER_Z_COORD, 1, 1, 1);
+  myZCoord = new QLineEdit(myEnfGroup);
+  myZCoord->setValidator(new QDoubleValidator(myEnfGroup));
+  anEnfLayout->addWidget(myZCoord, ENF_VER_Z_COORD, 2, 1, 1);
+
+  addVertexButton = new QPushButton(tr("BLSURF_ENF_VER_VERTEX"),myEnfGroup);
+  anEnfLayout->addWidget(addVertexButton, ENF_VER_VERTEX_BTN, 1, 1, 2);
+
+  QFrame *line = new QFrame(myEnfGroup);
+  line->setFrameShape(QFrame::HLine);
+  line->setFrameShadow(QFrame::Sunken);
+  anEnfLayout->addWidget(line, ENF_VER_SEPARATOR, 1, 1, 2);
+
+  removeVertexButton = new QPushButton(tr("BLSURF_ENF_VER_REMOVE"),myEnfGroup);
+  anEnfLayout->addWidget(removeVertexButton, ENF_VER_REMOVE_BTN, 1, 1, 2);
 
   // ---
   tab->insertTab( STD_TAB, myStdGroup, tr( "SMESH_ARGUMENTS" ) );
   tab->insertTab( ADV_TAB, myAdvGroup, tr( "BLSURF_ADV_ARGS" ) );
   tab->insertTab( SMP_TAB, mySmpGroup, tr( "BLSURF_SIZE_MAP" ) );
+  tab->insertTab( ENF_TAB, myEnfGroup, tr( "BLSURF_ENF_VER" ) );
 
   tab->setCurrentIndex( STD_TAB );
 
   // ---
-  connect( myGeometricMesh, SIGNAL( activated( int ) ), this, SLOT( onGeometricMeshChanged() ) );
-  connect( myPhysicalMesh,  SIGNAL( activated( int ) ), this, SLOT( onPhysicalMeshChanged() ) );
-  connect( addBtn->menu(),  SIGNAL( aboutToShow() ),    this, SLOT( onAddOption() ) );
-  connect( addBtn->menu(),  SIGNAL( triggered( QAction* ) ), this, SLOT( onOptionChosenInPopup( QAction* ) ) );
-  connect( rmBtn,           SIGNAL( clicked()),         this, SLOT( onDeleteOption() ) );
-
-  connect(addSurfaceButton, SIGNAL(clicked()), this, SLOT(onAddMapOnSurface()));
-  connect(addEdgeButton, SIGNAL(clicked()), this, SLOT(onAddMapOnEdge()));
-  connect(addPointButton, SIGNAL(clicked()), this, SLOT(onAddMapOnPoint()));
-  connect(removeButton, SIGNAL(clicked()), this, SLOT(onRemoveMap()));
-  connect(mySizeMapTable, SIGNAL(cellChanged ( int, int  )),this,SLOT (onSetSizeMap(int,int )));
+  connect( myGeometricMesh,    SIGNAL( activated( int ) ),            this,         SLOT( onGeometricMeshChanged() ) );
+  connect( myPhysicalMesh,     SIGNAL( activated( int ) ),            this,         SLOT( onPhysicalMeshChanged() ) );
+  connect( addBtn->menu(),     SIGNAL( aboutToShow() ),               this,         SLOT( onAddOption() ) );
+  connect( addBtn->menu(),     SIGNAL( triggered( QAction* ) ),       this,         SLOT( onOptionChosenInPopup( QAction* ) ) );
+  connect( rmBtn,              SIGNAL( clicked()),                    this,         SLOT( onDeleteOption() ) );
+
+  connect( addSurfaceButton,   SIGNAL( clicked()),                    this,         SLOT( onAddMapOnSurface() ) );
+  connect( addEdgeButton,      SIGNAL( clicked()),                    this,         SLOT( onAddMapOnEdge() ) );
+  connect( addPointButton,     SIGNAL( clicked()),                    this,         SLOT( onAddMapOnPoint() ) );
+  connect( removeButton,       SIGNAL( clicked()),                    this,         SLOT( onRemoveMap() ) );
+  connect( mySizeMapTable,     SIGNAL( cellChanged ( int, int  )),    this,         SLOT( onSetSizeMap(int,int ) ) );
+
+  connect( myEnforcedTreeWidget,SIGNAL( itemClicked(QTreeWidgetItem *, int)), this, SLOT( synchronizeCoords() ) );
+  connect( myEnforcedTreeWidget,SIGNAL( itemChanged(QTreeWidgetItem *, int)), this, SLOT( update(QTreeWidgetItem *, int) ) );
+  connect( myEnforcedTreeWidget,SIGNAL( itemSelectionChanged() ),     this,         SLOT( synchronizeCoords() ) );
+  connect( addVertexButton,    SIGNAL( clicked()),                    this,         SLOT( onAddEnforcedVertices() ) );
+  connect( removeVertexButton, SIGNAL( clicked()),                    this,         SLOT( onRemoveEnforcedVertex() ) );
 
   return fr;
 }
 
+/** BLSURFPluginGUI_HypothesisCreator::update(item, column)
+This method updates the tooltip of a modified item. The QLineEdit widgets content
+is synchronized with the coordinates of the enforced vertex clicked in the tree widget.
+*/
+void BLSURFPluginGUI_HypothesisCreator::update(QTreeWidgetItem* item, int column) {
+//   MESSAGE("BLSURFPluginGUI_HypothesisCreator::updateVertexList");
+  QVariant x = item->data(ENF_VER_X_COLUMN, Qt::EditRole);
+  if (not x.isNull()) {
+    QVariant y = item->data(ENF_VER_Y_COLUMN, Qt::EditRole);
+    QVariant z = item->data(ENF_VER_Z_COLUMN, Qt::EditRole);
+    QVariant vertexName = item->data(ENF_VER_NAME_COLUMN, Qt::EditRole);
+    
+    QTreeWidgetItem* parent = item->parent();
+    if (parent) {
+      QString shapeName = parent->data(ENF_VER_NAME_COLUMN, Qt::EditRole).toString();
+      QString toolTip = shapeName + QString(": ") + vertexName.toString();
+      toolTip += QString("(") + x.toString();
+      toolTip += QString(", ") + y.toString();
+      toolTip += QString(", ") + z.toString();
+      toolTip += QString(")");
+      item->setToolTip(ENF_VER_NAME_COLUMN,toolTip);
+    }
+    
+    myXCoord->setText(x.toString());
+    myYCoord->setText(y.toString());
+    myZCoord->setText(z.toString());
+  }
+}
+
+/** BLSURFPluginGUI_HypothesisCreator::synchronizeCoords()
+This method synchronizes the QLineEdit widgets content with the coordinates
+of the enforced vertex clicked in the tree widget.
+*/
+void BLSURFPluginGUI_HypothesisCreator::synchronizeCoords() {
+//   MESSAGE("BLSURFPluginGUI_HypothesisCreator::synchronizeCoords");
+  QList<QTreeWidgetItem *> items = myEnforcedTreeWidget->selectedItems();
+  if (not items.isEmpty()) {
+    QTreeWidgetItem *item;
+    for (int i=0 ; i < items.size() ; i++) {
+      item = items[i];
+      QVariant x = item->data(ENF_VER_X_COLUMN, Qt::EditRole);
+      if (not x.isNull()) {
+        QVariant y = item->data(ENF_VER_Y_COLUMN, Qt::EditRole);
+        QVariant z = item->data(ENF_VER_Z_COLUMN, Qt::EditRole);
+        myXCoord->setText(x.toString());
+        myYCoord->setText(y.toString());
+        myZCoord->setText(z.toString());
+        break;
+      }
+    }
+  }
+}
+
+/** BLSURFPluginGUI_HypothesisCreator::addEnforcedVertex(entry, shapeName, x, y, z)
+This method adds an enforced vertex (x,y,z) to shapeName in the tree widget.
+*/
+void BLSURFPluginGUI_HypothesisCreator::addEnforcedVertex(std::string entry, std::string shapeName, double x, double y, double z) {
+  // Find entry item
+  QList<QTreeWidgetItem* > theItemList = myEnforcedTreeWidget->findItems(QString(entry.c_str()),Qt::MatchExactly,ENF_VER_ENTRY_COLUMN);
+  QTreeWidgetItem* theItem;
+  if (theItemList.empty()) {
+    theItem = new QTreeWidgetItem();
+    theItem->setData(ENF_VER_ENTRY_COLUMN, Qt::EditRole, QVariant(entry.c_str()));
+    theItem->setData(ENF_VER_NAME_COLUMN, Qt::EditRole, QVariant(shapeName.c_str()));
+    theItem->setToolTip(ENF_VER_NAME_COLUMN,QString(entry.c_str()));
+    myEnforcedTreeWidget->addTopLevelItem(theItem);
+  }
+  else {
+    theItem = theItemList[0];
+  }
+
+//   MESSAGE("theItemName is " << theItem->text(ENF_VER_NAME_COLUMN).toStdString());
+  bool okToCreate = true;
+
+  const int nbVert = theItem->childCount();
+//   MESSAGE("Number of child rows: " << nbVert);
+  if (nbVert >0) {
+    double childValueX,childValueY,childValueZ;
+    QTreeWidgetItem* child;
+    for (int row = 0;row<nbVert;row++) {
+      child = theItem->child(row);
+      childValueX = child->data(ENF_VER_X_COLUMN,Qt::EditRole).toDouble();
+      childValueY = child->data(ENF_VER_Y_COLUMN,Qt::EditRole).toDouble();
+      childValueZ = child->data(ENF_VER_Z_COLUMN,Qt::EditRole).toDouble();
+      if ((childValueX == x) and (childValueY == y) and (childValueZ == z)) {
+        okToCreate = false;
+        break;
+      }
+    }
+  }
+  if (okToCreate) {
+    MESSAGE("In " << shapeName << " vertex with coords " << x << ", " << y << ", " << z<< " is created");
+    
+    QTreeWidgetItem *vertexItem = new QTreeWidgetItem( theItem);
+    vertexItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
+    int vertexIndex=1;
+    QString vertexName;
+    int indexRef = 0;
+    while(indexRef != vertexIndex) {
+      indexRef = vertexIndex;
+      vertexName = QString("Vertex #%1").arg(vertexIndex);
+      for (int row = 0;row<nbVert;row++) {
+        QString name = theItem->child(row)->data(ENF_VER_NAME_COLUMN,Qt::EditRole).toString();
+        if (vertexName == name) {
+          vertexIndex++;
+          break;
+        }
+      }
+    }
+    vertexItem->setData( ENF_VER_NAME_COLUMN, Qt::EditRole, vertexName );
+    vertexItem->setData( ENF_VER_X_COLUMN, Qt::EditRole, QVariant(x) );
+    vertexItem->setData( ENF_VER_Y_COLUMN, Qt::EditRole, QVariant(y) );
+    vertexItem->setData( ENF_VER_Z_COLUMN, Qt::EditRole, QVariant(z) );
+    QString toolTip = QString(shapeName.c_str())+QString(": ")+vertexName;
+    toolTip += QString(" (%1, ").arg(x);
+    toolTip += QString("%1, ").arg(y);
+    toolTip += QString("%1)").arg(z);
+    vertexItem->setToolTip(ENF_VER_NAME_COLUMN,toolTip);
+    theItem->setExpanded(true);
+    myEnforcedTreeWidget->setCurrentItem(vertexItem,ENF_VER_NAME_COLUMN);
+  }
+  else
+    MESSAGE("In " << shapeName << " vertex with coords " << x << ", " << y << ", " << z<< " already exist: dont create again");
+}
+
+/** BLSURFPluginGUI_HypothesisCreator::onAddEnforcedVertices()
+This method is called when a item is added into the enforced vertices tree widget
+*/
+void BLSURFPluginGUI_HypothesisCreator::onAddEnforcedVertices() {
+//   MESSAGE("BLSURFPluginGUI_HypothesisCreator::onAddEnforcedVertices");
+
+  for (int column = 0; column < myEnforcedTreeWidget->columnCount(); ++column)
+    myEnforcedTreeWidget->resizeColumnToContents(column);
+  
+  BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
+  
+  if ((myXCoord->text().isEmpty()) or (myYCoord->text().isEmpty()) or (myZCoord->text().isEmpty())) return;
+  
+  double x = myXCoord->text().toDouble();
+  double y = myYCoord->text().toDouble();
+  double z = myZCoord->text().toDouble();
+  
+  TopAbs_ShapeEnum shapeType;
+  string entry, shapeName;
+  GeomSelectionTools* myGeomToolSelected = that->getGeomSelectionTool();
+  LightApp_SelectionMgr* mySel = myGeomToolSelected->selectionMgr();
+  SALOME_ListIO ListSelectedObjects;
+  mySel->selectedObjects(ListSelectedObjects, NULL, false );
+  if (!ListSelectedObjects.IsEmpty()) {
+    SALOME_ListIteratorOfListIO Object_It(ListSelectedObjects);
+    for (; Object_It.More(); Object_It.Next()) {
+      Handle(SALOME_InteractiveObject) anObject = Object_It.Value();
+      entry     = myGeomToolSelected->getEntryOfObject(anObject);
+      shapeName = anObject->getName();
+      shapeType = myGeomToolSelected->entryToShapeType(entry);
+//       MESSAGE("Object Name = " << shapeName << "& Type is " << anObject->getComponentDataType() << " & ShapeType is " << shapeType);
+      if (shapeType == TopAbs_FACE) {
+        addEnforcedVertex(entry, shapeName, x, y, z);
+      }
+    }
+  }
+  for (int column = 0; column < myEnforcedTreeWidget->columnCount(); ++column)
+    myEnforcedTreeWidget->resizeColumnToContents(column);
+  
+  if ( myPhysicalMesh->currentIndex() != SizeMap ) {
+    myPhysicalMesh->setCurrentIndex( SizeMap );
+    onPhysicalMeshChanged();
+  }
+}
+
+/** BLSURFPluginGUI_HypothesisCreator::onRemoveEnforcedVertex()
+This method is called when a item is removed from the enforced vertices tree widget
+*/
+void BLSURFPluginGUI_HypothesisCreator::onRemoveEnforcedVertex() {
+//   MESSAGE("BLSURFPluginGUI_HypothesisCreator::onRemoveEnforcedVertex");
+  QList<QTreeWidgetItem *> selectedItems = myEnforcedTreeWidget->selectedItems();
+  QList<QTreeWidgetItem *> selectedVertices;
+  QSet<QTreeWidgetItem *> selectedEntries;
+  QTreeWidgetItem* item;
+
+  foreach( item, selectedItems ) {
+    QVariant value = item->data(ENF_VER_X_COLUMN, Qt::EditRole);
+    if (not value.isNull())
+      selectedVertices.append(item);
+    else
+      selectedEntries.insert(item);
+  }
+
+  foreach(item,selectedVertices) {
+    QTreeWidgetItem* parent = item->parent();
+//     MESSAGE("From geometry "<< parent->text(ENF_VER_NAME_COLUMN).toStdString()<<" remove " << item->text(ENF_VER_NAME_COLUMN).toStdString());
+    parent->removeChild(item);
+    delete item;
+    if (parent->childCount() == 0) {
+      if (selectedEntries.contains(parent))
+        selectedEntries.remove(parent);
+      delete parent;
+    }
+  }
+
+  foreach(item,selectedEntries) {
+//     MESSAGE("Remove " << item->text(ENF_VER_NAME_COLUMN).toStdString());
+    delete item;
+  }
+
+  myEnforcedTreeWidget->selectionModel()->clearSelection();
+}
+
+/** BLSURFPluginGUI_HypothesisCreator::retrieveParams()
+This method updates the GUI widgets with the hypothesis data
+*/
 void BLSURFPluginGUI_HypothesisCreator::retrieveParams() const
 {
   MESSAGE("BLSURFPluginGUI_HypothesisCreator::retrieveParams");
@@ -611,7 +1043,7 @@ void BLSURFPluginGUI_HypothesisCreator::retrieveParams() const
   myVerbosity->setValue( data.myVerbosity );
 
   if ( myOptions.operator->() ) {
-    printf("retrieveParams():myOptions->length()=%d\n",myOptions->length());
+//     MESSAGE("retrieveParams():myOptions->length() = " << myOptions->length());
     for ( int i = 0, nb = myOptions->length(); i < nb; ++i ) {
       QString option = that->myOptions[i].in();
       QStringList name_value = option.split( ":", QString::KeepEmptyParts );
@@ -632,7 +1064,8 @@ void BLSURFPluginGUI_HypothesisCreator::retrieveParams() const
   }
   myOptionTable->resizeColumnToContents( OPTION_NAME_COLUMN );
 
-  printf("retrieveParams():that->mySMPMap.size()=%d\n",that->mySMPMap.size());
+  // Sizemaps
+//   MESSAGE("retrieveParams():that->mySMPMap.size() = " << that->mySMPMap.size());
   QMapIterator<QString, QString> i(that->mySMPMap);
   GeomSelectionTools* myGeomToolSelected = that->getGeomSelectionTool();
   while (i.hasNext()) {
@@ -655,11 +1088,43 @@ void BLSURFPluginGUI_HypothesisCreator::retrieveParams() const
   mySizeMapTable->resizeColumnToContents( SMP_NAME_COLUMN );
   mySizeMapTable->resizeColumnToContents(SMP_SIZEMAP_COLUMN);
 
+  // Enforced vertices
+//   MESSAGE("retrieveParams(): data.enfVertMap.size() = " << data.enfVertMap.size());
+  std::map<std::string, std::set<std::vector<double> > >::const_iterator evmIt = data.enfVertMap.begin();
+  for ( ; evmIt != data.enfVertMap.end() ; ++evmIt) {
+    std::string entry = (*evmIt).first;
+    std::string shapeName = myGeomToolSelected->getNameFromEntry(entry);
+
+    std::set<std::vector<double> > evs;
+    std::set<std::vector<double> >::const_iterator evsIt;
+    try  {
+      evs = (*evmIt).second;
+    }
+    catch(...) {
+//       MESSAGE("evs = (*evmIt)[entry]: FAIL");
+      break;
+    }
+
+    evsIt = evs.begin();
+    for ( ; evsIt != evs.end() ; ++evsIt) {
+      double x, y, z;
+      x = (*evsIt)[0];
+      y = (*evsIt)[1];
+      z = (*evsIt)[2];
+      that->addEnforcedVertex(entry, shapeName, x, y, z);
+    }
+  }
+  for (int column = 0; column < myEnforcedTreeWidget->columnCount(); ++column)
+    myEnforcedTreeWidget->resizeColumnToContents(column);
+  
   // update widgets
   that->onPhysicalMeshChanged();
   that->onGeometricMeshChanged();
 }
 
+/** BLSURFPluginGUI_HypothesisCreator::storeParams()
+This method updates the hypothesis data with the GUI widgets content.
+*/
 QString BLSURFPluginGUI_HypothesisCreator::storeParams() const
 {
   BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
@@ -671,6 +1136,9 @@ QString BLSURFPluginGUI_HypothesisCreator::storeParams() const
   return guiHyp;
 }
 
+/** BLSURFPluginGUI_HypothesisCreator::readParamsFromHypo(h_data)
+Updates the hypothesis data from hypothesis values.
+*/
 bool BLSURFPluginGUI_HypothesisCreator::readParamsFromHypo( BlsurfHypothesisData& h_data ) const
 {
   MESSAGE("BLSURFPluginGUI_HypothesisCreator::readParamsFromHypo");
@@ -710,22 +1178,29 @@ bool BLSURFPluginGUI_HypothesisCreator::readParamsFromHypo( BlsurfHypothesisData
 
   // classic size maps
   BLSURFPlugin::string_array_var mySizeMaps = h->GetSizeMapEntries();
-  MESSAGE("mySizeMaps->length() = " << mySizeMaps->length());
+//   MESSAGE("mySizeMaps->length() = " << mySizeMaps->length());
   QString fullSizeMaps;
   QStringList fullSizeMapList;
   GeomSelectionTools* myGeomToolSelected = that->getGeomSelectionTool();
   for ( int i = 0;i<mySizeMaps->length(); ++i ) {
     fullSizeMaps =  mySizeMaps[i].in();
-    MESSAGE("fullSizeMaps: " << fullSizeMaps.toStdString());
+//     MESSAGE("fullSizeMaps: " << fullSizeMaps.toStdString());
     fullSizeMapList = fullSizeMaps.split( "|", QString::KeepEmptyParts );
     if ( fullSizeMapList.count() > 1 ) {
       string fullSizeMap = fullSizeMapList[1].toStdString();
       int pos = fullSizeMap.find("return")+7;
-      QString sizeMap = QString::fromStdString(fullSizeMap.substr(pos, fullSizeMap.size()-pos));
+//       MESSAGE("pos:" << pos);
+      QString sizeMap;
+      try {
+        sizeMap = QString::fromStdString(fullSizeMap.substr(pos, fullSizeMap.size()-pos));
+      }
+      catch (...) {
+        continue;
+      }
       that->mySMPMap[fullSizeMapList[0]] = sizeMap;
-      MESSAGE("mySMPMap[" << fullSizeMapList[0].toStdString() << "] = " << sizeMap.toStdString());
-      that->mySMPShapeTypeMap[fullSizeMapList[0]] = myGeomToolSelected->entryToShape(fullSizeMapList[0].toStdString()).ShapeType();
-      MESSAGE("mySMPShapeTypeMap[" << fullSizeMapList[0].toStdString() << "] = " << that->mySMPShapeTypeMap[fullSizeMapList[0]]);
+//       MESSAGE("mySMPMap[" << fullSizeMapList[0].toStdString() << "] = " << sizeMap.toStdString());
+      that->mySMPShapeTypeMap[fullSizeMapList[0]] = myGeomToolSelected->entryToShapeType(fullSizeMapList[0].toStdString());
+//       MESSAGE("mySMPShapeTypeMap[" << fullSizeMapList[0].toStdString() << "] = " << that->mySMPShapeTypeMap[fullSizeMapList[0]]);
     }
   }
 
@@ -739,7 +1214,7 @@ bool BLSURFPluginGUI_HypothesisCreator::readParamsFromHypo( BlsurfHypothesisData
     QStringList fullCustomSizeMapList = fullCustomSizeMaps.split( "|", QString::KeepEmptyParts );
     if ( fullCustomSizeMapList.count() > 1 ) {
       that->mySMPMap[fullCustomSizeMapList[0]] = fullCustomSizeMapList[1];
-      that->mySMPShapeTypeMap[fullCustomSizeMapList[0]] = GeomToolSelected->entryToShape(fullCustomSizeMapList[0].toStdString()).ShapeType();
+      that->mySMPShapeTypeMap[fullCustomSizeMapList[0]] = GeomToolSelected->entryToShapeType(fullCustomSizeMapList[0].toStdString());
       MESSAGE("mySMPMap[" << fullCustomSizeMapList[0].toStdString() << "] = " << fullCustomSizeMapList[1].toStdString());
       MESSAGE("mySMPShapeTypeMap[" << fullCustomSizeMapList[0].toStdString() << "] = " << that->mySMPShapeTypeMap[fullCustomSizeMapList[0]]);
     }
@@ -747,22 +1222,52 @@ bool BLSURFPluginGUI_HypothesisCreator::readParamsFromHypo( BlsurfHypothesisData
 */
   // attractor
   BLSURFPlugin::string_array_var allMyAttractors = h->GetAttractorEntries();
-  MESSAGE("myAttractors->length() = " << allMyAttractors->length());
+//   MESSAGE("myAttractors->length() = " << allMyAttractors->length());
 
   for ( int i = 0;i<allMyAttractors->length(); ++i ) {
     QString myAttractors =  allMyAttractors[i].in();
     QStringList myAttractorList = myAttractors.split( "|", QString::KeepEmptyParts );
     if ( myAttractorList.count() > 1 ) {
       that->mySMPMap[myAttractorList[0]] = myAttractorList[1];
-      that->mySMPShapeTypeMap[myAttractorList[0]] = myGeomToolSelected->entryToShape(myAttractorList[0].toStdString()).ShapeType();
-      MESSAGE("mySMPMap[" << myAttractorList[0].toStdString() << "] = " << myAttractorList[1].toStdString());
-      MESSAGE("mySMPShapeTypeMap[" << myAttractorList[0].toStdString() << "] = " << that->mySMPShapeTypeMap[myAttractorList[0]]);
+      that->mySMPShapeTypeMap[myAttractorList[0]] = myGeomToolSelected->entryToShapeType(myAttractorList[0].toStdString());
+//       MESSAGE("mySMPMap[" << myAttractorList[0].toStdString() << "] = " << myAttractorList[1].toStdString());
+//       MESSAGE("mySMPShapeTypeMap[" << myAttractorList[0].toStdString() << "] = " << that->mySMPShapeTypeMap[myAttractorList[0]]);
     }
   }
-
+  
+  // Enforced vertices
+  BLSURFPlugin::TEnforcedVertexMap_var enforcedVertexMap = h->GetAllEnforcedVertices();
+//   MESSAGE("enforcedVertexMap->length() = " << enforcedVertexMap->length());
+  
+  for ( int i = 0;i<enforcedVertexMap->length(); ++i ) {
+    std::string entry =  enforcedVertexMap[i].entry.in();
+//     BLSURFPlugin::TEnforcedVertexList_var vertexList = enforcedVertexMap[i].vertexList;
+    BLSURFPlugin::TEnforcedVertexList vertexList = enforcedVertexMap[i].vertexList;
+    std::set<std::vector<double> > evs;
+    for (int j=0 ; j<vertexList.length(); ++j) {
+      double x = vertexList[j][0];
+      double y = vertexList[j][1];
+      double z = vertexList[j][2];
+      std::vector<double> ev;
+      ev.push_back(x);
+      ev.push_back(y);
+      ev.push_back(z);
+      evs.insert(ev);
+//       MESSAGE("New enf vertex for entry " << entry << ": " << x << ", " << y << ", " << z);
+    }
+    h_data.enfVertMap[entry] = evs;
+    if (evs.size() == 0) {
+//       MESSAGE("No enf vertex for entry " << entry << ": key is erased");
+      h_data.enfVertMap.erase(entry);
+    }
+  }
+  
   return true;
 }
 
+/** BLSURFPluginGUI_HypothesisCreator::storeParamsToHypo(h_data)
+Saves the hypothesis data to hypothesis values.
+*/
 bool BLSURFPluginGUI_HypothesisCreator::storeParamsToHypo( const BlsurfHypothesisData& h_data ) const
 {
   MESSAGE("BLSURFPluginGUI_HypothesisCreator::storeParamsToHypo");
@@ -831,15 +1336,15 @@ bool BLSURFPluginGUI_HypothesisCreator::storeParamsToHypo( const BlsurfHypothesi
       const QString sizeMap = i.value();
 
       if (sizeMap == "__TO_DELETE__") {
-        MESSAGE("Delete entry " << entry.toStdString() << " from engine");
+//         MESSAGE("Delete entry " << entry.toStdString() << " from engine");
         h->UnsetEntry(entry.toLatin1().constData());
       }
       else if (sizeMap.startsWith("ATTRACTOR")) {
-        MESSAGE("SetAttractorEntry(" << entry.toStdString() << ")= " << sizeMap.toStdString());
+//         MESSAGE("SetAttractorEntry(" << entry.toStdString() << ")= " << sizeMap.toStdString());
         h->SetAttractorEntry( entry.toLatin1().constData(), sizeMap.toLatin1().constData() );
       }
       else if (sizeMap.startsWith("def")) {
-        MESSAGE("SetCustomSizeMapEntry(" << entry.toStdString() << ")= " << sizeMap.toStdString());
+//         MESSAGE("SetCustomSizeMapEntry(" << entry.toStdString() << ")= " << sizeMap.toStdString());
 //        h->SetCustomSizeMapEntry( entry.toLatin1().constData(), sizeMap.toLatin1().constData() );
       }
       else {
@@ -852,10 +1357,52 @@ bool BLSURFPluginGUI_HypothesisCreator::storeParamsToHypo( const BlsurfHypothesi
         else if (that->mySMPShapeTypeMap[entry] == TopAbs_VERTEX)
           fullSizeMap = QString("def f(): return ") + sizeMap;
 
-        MESSAGE("SetSizeMapEntry("<<entry.toStdString()<<") = " <<fullSizeMap.toStdString());
+//         MESSAGE("SetSizeMapEntry("<<entry.toStdString()<<") = " <<fullSizeMap.toStdString());
         h->SetSizeMapEntry( entry.toLatin1().constData(), fullSizeMap.toLatin1().constData() );
       }
     }
+    
+    // Enforced vertices
+    std::map<std::string, std::set<std::vector<double> > >::const_iterator evmIt = h_data.enfVertMap.begin();
+    for ( ; evmIt != h_data.enfVertMap.end() ; ++evmIt) {
+      std::string entry = evmIt->first;
+      std::set<std::vector<double> > evs;
+      std::set<std::vector<double> >::const_iterator evsIt;
+      double x, y, z;
+      BLSURFPlugin::TEnforcedVertexList_var hypVertexList;
+      int hypNbVertex = 0;
+      try {
+        hypVertexList = h->GetEnforcedVerticesEntry(entry.c_str());
+        hypNbVertex = hypVertexList->length();
+      }
+      catch(...) {
+      }
+      evs = evmIt->second;
+      evsIt = evs.begin();
+      for ( ; evsIt != evs.end() ; ++evsIt) {
+        x = (*evsIt)[0];
+        y = (*evsIt)[1];
+        z = (*evsIt)[2];
+//         MESSAGE("SetEnforcedVertexEntry("<<entry<<", "<<x<<", "<<y<<", "<<z<<")");
+        h->SetEnforcedVertexEntry( entry.c_str(), x, y, z );
+      }
+      // Remove old vertices
+      if (hypNbVertex >0) {
+        for (int i =0 ; i<hypNbVertex ; i++) {
+          x = hypVertexList[i][0];
+          y = hypVertexList[i][1];
+          z = hypVertexList[i][2];
+          std::vector<double> vertex;
+          vertex.push_back(x);
+          vertex.push_back(y);
+          vertex.push_back(z);
+          if (evs.find(vertex) == evs.end()) {
+//             MESSAGE("UnsetEnforcedVertexEntry("<<entry<<", "<<x<<", "<<y<<", "<<z<<")");
+            h->UnsetEnforcedVertexEntry( entry.c_str(), x, y, z );
+          }
+        }
+      }
+    }
   }
   catch(const SALOME::SALOME_Exception& ex)
   {
@@ -865,6 +1412,9 @@ bool BLSURFPluginGUI_HypothesisCreator::storeParamsToHypo( const BlsurfHypothesi
   return ok;
 }
 
+/** BLSURFPluginGUI_HypothesisCreator::readParamsFromWidgets(h_data)
+Stores the widgets content to the hypothesis data.
+*/
 QString BLSURFPluginGUI_HypothesisCreator::readParamsFromWidgets( BlsurfHypothesisData& h_data ) const
 {
   MESSAGE("BLSURFPluginGUI_HypothesisCreator::readParamsFromWidgets");
@@ -925,21 +1475,67 @@ QString BLSURFPluginGUI_HypothesisCreator::readParamsFromWidgets( BlsurfHypothes
   {
       QString entry   = mySizeMapTable->item( row, SMP_ENTRY_COLUMN )->text();
       if ( that->mySMPMap.contains(entry) )
-        guiHyp += entry + " = " + that->mySMPMap[entry] + "; ";
+        guiHyp += "SetSizeMapEntry(" + entry + ", " + that->mySMPMap[entry] + "); ";
   }
 
-  MESSAGE("guiHyp : " << guiHyp.toLatin1().data());
+  // Enforced vertices
+  // h_data.enfVertMap
+
+  int nbEnforcedShapes = myEnforcedTreeWidget->topLevelItemCount();
+  int nbEnforcedVertices = 0;
+//   MESSAGE("Nb of enforced shapes: " << nbEnforcedShapes);
+  for (int i=0 ; i<nbEnforcedShapes ; i++) {
+    QTreeWidgetItem* shapeItem = myEnforcedTreeWidget->topLevelItem(i);
+    if (shapeItem) {
+      std::string entry = shapeItem->data(ENF_VER_ENTRY_COLUMN,Qt::EditRole).toString().toStdString();
+      nbEnforcedVertices = shapeItem->childCount();
+      if (nbEnforcedVertices >0) {
+        double childValueX,childValueY,childValueZ;
+        QTreeWidgetItem* child;
+        std::set<std::vector<double> > evs;
+        for (row = 0;row<nbEnforcedVertices;row++) {
+          child = shapeItem->child(row);
+          childValueX = child->data(ENF_VER_X_COLUMN,Qt::EditRole).toDouble();
+          childValueY = child->data(ENF_VER_Y_COLUMN,Qt::EditRole).toDouble();
+          childValueZ = child->data(ENF_VER_Z_COLUMN,Qt::EditRole).toDouble();
+          std::vector<double> vertex;
+          vertex.push_back(childValueX);
+          vertex.push_back(childValueY);
+          vertex.push_back(childValueZ);
+          evs.insert(vertex);
+        }
+        h_data.enfVertMap[entry] = evs;
+      }
+    }
+  }
 
+  MESSAGE("guiHyp : " << guiHyp.toLatin1().data());
   return guiHyp;
 }
 
 void BLSURFPluginGUI_HypothesisCreator::onPhysicalMeshChanged() {
   MESSAGE("BLSURFPluginGUI_HypothesisCreator::onPhysicalMeshChanged");
-  bool isCustom = ((myPhysicalMesh->currentIndex() == PhysicalUserDefined) || (myPhysicalMesh->currentIndex() == SizeMap)) ;
+  bool isPhysicalUserDefined = (myPhysicalMesh->currentIndex() == PhysicalUserDefined);
+  bool isSizeMap = (myPhysicalMesh->currentIndex() == SizeMap);
+  bool isCustom = (isPhysicalUserDefined || isSizeMap) ;
+  bool geomIsCustom = (myGeometricMesh->currentIndex() == UserDefined);
+  
+  myGradation->setEnabled(not isPhysicalUserDefined || geomIsCustom);
   myPhySize->setEnabled(isCustom);
   myPhyMax->setEnabled(isCustom);
   myPhyMin->setEnabled(isCustom);
 
+  if ( !isSizeMap) {
+    double gradation;
+    switch( myPhysicalMesh->currentIndex() ) {
+      case DefaultSize:
+      default:
+        gradation = 1.1;
+        break;
+    }
+    myGradation->setValue( gradation );
+  }
+      
   if ( !isCustom ) {
     QString aPhySize = "";
     switch( myPhysicalMesh->currentIndex() ) {
@@ -963,24 +1559,24 @@ void BLSURFPluginGUI_HypothesisCreator::onPhysicalMeshChanged() {
 void BLSURFPluginGUI_HypothesisCreator::onGeometricMeshChanged() {
   MESSAGE("BLSURFPluginGUI_HypothesisCreator::onGeometricMeshChanged");
   bool isCustom = (myGeometricMesh->currentIndex() == UserDefined);
+  bool phyIsSizemap = (myPhysicalMesh->currentIndex() == SizeMap);
+  
   myAngleMeshS->setEnabled(isCustom);
   myAngleMeshC->setEnabled(isCustom);
-  myGradation->setEnabled(isCustom);
+  myGradation->setEnabled(isCustom || phyIsSizemap);
   myGeoMax->setEnabled(isCustom);
   myGeoMin->setEnabled(isCustom);
 
   if ( ! isCustom ) {
-    double aAngleMeshS, aGradation;
+    double aAngleMeshS;
     switch( myGeometricMesh->currentIndex() ) {
       case DefaultGeom:
       default:
         aAngleMeshS = 8;
-        aGradation = 1.1;
         break;
       }
     myAngleMeshS->setValue( aAngleMeshS );
     myAngleMeshC->setValue( aAngleMeshS );
-    myGradation->setValue( aGradation );
     if ( !isDouble( myGeoMin->text(), true ))
       myGeoMin->setText("");
     if ( !isDouble( myGeoMax->text(), true ))
@@ -1107,8 +1703,8 @@ void BLSURFPluginGUI_HypothesisCreator::onSetSizeMap(int row,int col)
     BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
     QString entry   = that->mySizeMapTable->item(row, SMP_ENTRY_COLUMN)->text();
     QString sizeMap = that->mySizeMapTable->item(row, SMP_SIZEMAP_COLUMN)->text().trimmed();
-    MESSAGE("entry: " << entry.toStdString() << ", sizeMap: " << sizeMap.toStdString());
-    if (! that->mySMPShapeTypeMap.contains(entry))
+//     MESSAGE("entry: " << entry.toStdString() << ", sizeMap: " << sizeMap.toStdString());
+    if (not that->mySMPShapeTypeMap.contains(entry))
       return;
     if (that->mySMPMap.contains(entry))
       if (that->mySMPMap[entry] == sizeMap)
@@ -1123,7 +1719,7 @@ void BLSURFPluginGUI_HypothesisCreator::onSetSizeMap(int row,int col)
       }
     }
     else {
-      MESSAGE("Size map empty: reverse to precedent value" );
+//       MESSAGE("Size map empty: reverse to precedent value" );
       that->mySizeMapTable->item(row, SMP_SIZEMAP_COLUMN)->setText(that->mySMPMap[entry]);
     }
     that->mySizeMapTable->item(row, SMP_NAME_COLUMN)->setBackground(QBrush(*bgColor));
@@ -1151,14 +1747,14 @@ void BLSURFPluginGUI_HypothesisCreator::onAddMapOnPoint()
 
 void BLSURFPluginGUI_HypothesisCreator::insertElementType(TopAbs_ShapeEnum typeShapeAsked)
 {
-  MESSAGE("BLSURFPluginGUI_HypothesisCreator::insertElementType()");
+//   MESSAGE("BLSURFPluginGUI_HypothesisCreator::insertElementType()");
 
   BLSURFPlugin::BLSURFPlugin_Hypothesis_var h =
     BLSURFPlugin::BLSURFPlugin_Hypothesis::_narrow( initParamsHypothesis());
 
   BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
 
-  TopoDS_Shape S;
+  TopAbs_ShapeEnum shapeType;
   string entry, shapeName;
   GeomSelectionTools* myGeomToolSelected = that->getGeomSelectionTool();
 
@@ -1174,8 +1770,9 @@ void BLSURFPluginGUI_HypothesisCreator::insertElementType(TopAbs_ShapeEnum typeS
       Handle(SALOME_InteractiveObject) anObject = Object_It.Value();
       entry     = myGeomToolSelected->getEntryOfObject(anObject);
       shapeName = anObject->getName();
-      S         = myGeomToolSelected->entryToShape(entry);
-      if ((! S.IsNull()) && (S.ShapeType() == typeShapeAsked))
+      shapeType         = myGeomToolSelected->entryToShapeType(entry);
+//       MESSAGE("Object Name = " << shapeName << "& Type is " << anObject->getComponentDataType() << " & ShapeType is " << shapeType);
+      if (shapeType == typeShapeAsked)
       {
         mySizeMapTable->setFocus();
         QString shapeEntry;
@@ -1187,7 +1784,7 @@ void BLSURFPluginGUI_HypothesisCreator::insertElementType(TopAbs_ShapeEnum typeS
         sizeMap  = QString::fromStdString(oss.str());
         if (that->mySMPMap.contains(shapeEntry)) {
           if (that->mySMPMap[shapeEntry] != "__TO_DELETE__") {
-            MESSAGE("Size map for shape with name(entry): "<< shapeName << "(" << entry << ")");
+//             MESSAGE("Size map for shape with name(entry): "<< shapeName << "(" << entry << ")");
             break;
           }
         }
@@ -1217,7 +1814,7 @@ void BLSURFPluginGUI_HypothesisCreator::insertElementType(TopAbs_ShapeEnum typeS
 
 bool BLSURFPluginGUI_HypothesisCreator::sizeMapsValidation()
 {
-  MESSAGE("BLSURFPluginGUI_HypothesisCreator::sizeMapsValidation()");
+//   MESSAGE("BLSURFPluginGUI_HypothesisCreator::sizeMapsValidation()");
   int row = 0, nbRows = mySizeMapTable->rowCount();
   for ( ; row < nbRows; ++row )
     if (! sizeMapValidationFromRow(row))
@@ -1227,7 +1824,7 @@ bool BLSURFPluginGUI_HypothesisCreator::sizeMapsValidation()
 
 bool BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromRow(int myRow, bool displayError)
 {
-  MESSAGE("BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromRow()");
+//   MESSAGE("BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromRow()");
   QString myEntry   = mySizeMapTable->item( myRow, SMP_ENTRY_COLUMN )->text();
   bool res = sizeMapValidationFromEntry(myEntry,displayError);
   mySizeMapTable->setFocus();
@@ -1236,34 +1833,34 @@ bool BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromRow(int myRow, bool
 
 bool BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromEntry(QString myEntry, bool displayError)
 {
-  MESSAGE("BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromEntry()");
+//   MESSAGE("BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromEntry()");
 
   BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
 
-  if (! that->mySMPMap.contains(myEntry)) {
-    MESSAGE("Geometry with entry "<<myEntry.toStdString()<<" was not found.");
+  if (not that->mySMPMap.contains(myEntry)) {
+//     MESSAGE("Geometry with entry "<<myEntry.toStdString()<<" was not found.");
     return false;
   }
-  if (! that->mySMPShapeTypeMap.contains(myEntry)) {
-    MESSAGE("Shape type with entry "<<myEntry.toStdString()<<" was not found.");
+  if (not that->mySMPShapeTypeMap.contains(myEntry)) {
+//     MESSAGE("Shape type with entry "<<myEntry.toStdString()<<" was not found.");
     return false;
   }
 
   string expr;
 
   if (that->mySMPMap[myEntry].startsWith("def")) {
-    MESSAGE("custom function" );
+//     MESSAGE("custom function" );
     expr = that->mySMPMap[myEntry].toStdString();
   }
   else if (that->mySMPMap[myEntry].startsWith("ATTRACTOR")) {
-    MESSAGE("Attractor" );
-//    if ((that->mySMPMap[myEntry].count(QRegExp("ATTRACTOR([0-9])")) != 1))
-    if ((that->mySMPMap[myEntry].count('(') != 1) ||
-        (that->mySMPMap[myEntry].count(')') != 1) ||
-        (that->mySMPMap[myEntry].count(';') != 4) ||
-        (that->mySMPMap[myEntry].size() == 15)){
+//     MESSAGE("Attractor" );
+    if ((that->mySMPMap[myEntry].count(QRegExp("^ATTRACTOR\\((?:(-?0(\\.\\d*)*|-?[1-9]+\\d*(\\.\\d*)*|-?\\.(\\d)+);){5}(True|False)\\)$")) != 1)) {
+//     if ((that->mySMPMap[myEntry].count('(') != 1) or
+//         (that->mySMPMap[myEntry].count(')') != 1) or
+//         (that->mySMPMap[myEntry].count(';') != 4) or
+//         (that->mySMPMap[myEntry].size() == 15)){
       if (displayError)
-        SUIT_MessageBox::warning( dlg(),"Definition of attractor : Error" ,"An attractor is defined with the following pattern: ATTRACTOR(xa;ya;za;a;b)" );
+        SUIT_MessageBox::warning( dlg(),"Definition of attractor : Error" ,"An attractor is defined with the following pattern: ATTRACTOR(xa;ya;za;a;b;True|False)" );
       return false;
     }
     return true;
@@ -1275,13 +1872,14 @@ bool BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromEntry(QString myEnt
         SUIT_MessageBox::warning( dlg(),"Definition of size map : Error" , "Size map can't be empty");
       return false;
     }
-
-    if ( that->mySMPShapeTypeMap[myEntry] == TopAbs_FACE)
-      expr = "def f(u,v) : return " + that->mySMPMap[myEntry].toStdString();
-    else if ( that->mySMPShapeTypeMap[myEntry] == TopAbs_EDGE)
-      expr = "def f(t) : return " + that->mySMPMap[myEntry].toStdString();
-    else if ( that->mySMPShapeTypeMap[myEntry] == TopAbs_VERTEX)
-      expr = "def f() : return " + that->mySMPMap[myEntry].toStdString();
+    else {
+      if ( that->mySMPShapeTypeMap[myEntry] == TopAbs_FACE)
+        expr = "def f(u,v) : return " + that->mySMPMap[myEntry].toStdString();
+      else if ( that->mySMPShapeTypeMap[myEntry] == TopAbs_EDGE)
+        expr = "def f(t) : return " + that->mySMPMap[myEntry].toStdString();
+      else if ( that->mySMPShapeTypeMap[myEntry] == TopAbs_VERTEX)
+        expr = "def f() : return " + that->mySMPMap[myEntry].toStdString();
+    }
   }
   //assert(Py_IsInitialized());
   if (! Py_IsInitialized())
@@ -1326,7 +1924,7 @@ bool BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromEntry(QString myEnt
 
   PyGILState_Release(gstate);
 
-  MESSAGE("SizeMap expression "<<expr<<" is valid");
+//   MESSAGE("SizeMap expression "<<expr<<" is valid");
 
   return true;
 }
@@ -1398,3 +1996,4 @@ LightApp_SelectionMgr* BLSURFPluginGUI_HypothesisCreator::selectionMgr()
     return 0;
 }
 
+
index b66f74f169d57d90167651cfab2c2f7871704204..2e9ca666546def7e2b8c0b73914e330a4941b170 100644 (file)
 #endif
 
 #include <Python.h>
+
+#include <QItemDelegate>
+
 #include <SMESHGUI_Hypotheses.h>
 #include <SALOMEconfig.h>
 #include <cstring>
 #include <map>
+#include <set>
+#include <vector>
 #include <TopAbs_ShapeEnum.hxx>
 #include <GeomSelectionTools.h>
 #include CORBA_SERVER_HEADER(BLSURFPlugin_Algorithm)
 
 class QGroupBox;
-class QtxDoubleSpinBox;
 class QComboBox;
 class QCheckBox;
 class QLineEdit;
 class QTableWidget;
-class QTableView;
+class QTreeWidget;
 class QModelIndex;
 class QSpinBox;
 class QMenu;
 class QAction;
+class QTreeWidgetItem;
+
+class SalomeApp_DoubleSpinBox;
 class LightApp_SelectionMgr;
 
 typedef struct
@@ -72,7 +79,8 @@ typedef struct
   int     myPhysicalMesh, myGeometricMesh;
   double  myAngleMeshS, myAngleMeshC, myGradation;
   QString myPhySize, myGeoMin, myGeoMax, myPhyMin,myPhyMax;
-  bool    myAllowQuadrangles, myDecimesh,mySmpsurface,mySmpedge,mySmppoint;
+  bool    myAllowQuadrangles, myDecimesh,mySmpsurface,mySmpedge,mySmppoint,myEnforcedVertex;
+  std::map<std::string, std::set<std::vector<double> > > enfVertMap;
   QString myName;
 } BlsurfHypothesisData;
 
@@ -108,12 +116,19 @@ protected slots:
   void                onAddOption();
   void                onDeleteOption();
   void                onOptionChosenInPopup( QAction* );
+//  void                onAddAttractor();
   void                onAddMapOnSurface();
   void                onAddMapOnEdge();
   void                onAddMapOnPoint();
   void                onRemoveMap();
   void                onSetSizeMap(int,int);
 
+  void                addEnforcedVertex(std::string, std::string, double, double, double);
+  void                onAddEnforcedVertices();
+  void                onRemoveEnforcedVertex();
+  void                synchronizeCoords();
+  void                update(QTreeWidgetItem* , int );
+
 private:
   bool                readParamsFromHypo( BlsurfHypothesisData& ) const;
   QString             readParamsFromWidgets( BlsurfHypothesisData& ) const;
@@ -131,11 +146,11 @@ private:
   QLineEdit*          myPhyMin;
   QLineEdit*          myPhyMax;
   QComboBox*          myGeometricMesh;
-  QtxDoubleSpinBox*   myAngleMeshS;
-  QtxDoubleSpinBox*   myAngleMeshC;
+  SalomeApp_DoubleSpinBox*   myAngleMeshS;
+  SalomeApp_DoubleSpinBox*   myAngleMeshC;
   QLineEdit*          myGeoMin;
   QLineEdit*          myGeoMax;
-  QtxDoubleSpinBox*   myGradation;
+  SalomeApp_DoubleSpinBox*   myGradation;
   QCheckBox*          myAllowQuadrangles;
   QCheckBox*          myDecimesh;
 
@@ -144,7 +159,7 @@ private:
   QSpinBox*           myVerbosity;
   QTableWidget*       myOptionTable;
 
-  QWidget             *mySmpGroup;  
+  QWidget             *mySmpGroup;
   QTableWidget        *mySizeMapTable;
   QPushButton         *addAttractorButton;
   QPushButton         *addSurfaceButton;
@@ -152,6 +167,14 @@ private:
   QPushButton         *addPointButton;
   QPushButton         *removeButton;
 
+  QWidget*            myEnfGroup;
+  QTreeWidget*        myEnforcedTreeWidget;
+  QLineEdit*          myXCoord;
+  QLineEdit*          myYCoord;
+  QLineEdit*          myZCoord;
+  QPushButton*        addVertexButton;
+  QPushButton*        removeVertexButton;
+
   // map =  entry , size map
   QMap<QString, QString>          mySMPMap;
   QMap<QString, TopAbs_ShapeEnum> mySMPShapeTypeMap;
@@ -164,4 +187,25 @@ private:
   PyObject *          main_dict;
 };
 
+
+class EnforcedTreeWidgetDelegate : public QItemDelegate
+{
+    Q_OBJECT
+
+public:
+  EnforcedTreeWidgetDelegate(QObject *parent = 0);
+
+  QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
+                        const QModelIndex &index) const;
+
+  void setEditorData(QWidget *editor, const QModelIndex &index) const;
+  void setModelData(QWidget *editor, QAbstractItemModel *model,
+                    const QModelIndex &index) const;
+
+  void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
+                    const QModelIndex &index) const;
+  
+  bool vertexExists(QAbstractItemModel *model, const QModelIndex &index, QString value) const;
+};
+
 #endif // BLSURFPLUGINGUI_HypothesisCreator_H
index 5fb60b85c16258312ac0fd0b04549deaff96a35a..6a669a9f1b7b2270b2218b8b6ed1969d31f7f266 100644 (file)
             <source>BLSURF_PHY_MESH</source>
             <translation>Physical Mesh</translation>
         </message>
+        <message>
+            <source>BLSURF_ADV_ARGS</source>
+            <translation>Advanced</translation>
+        </message>
+        <message>
+            <source>BLSURF_TITLE</source>
+            <translation>Hypothesis Construction</translation>
+        </message>
+        <message>
+            <source>BLSURF_TOPOLOGY</source>
+            <translation>Topology</translation>
+        </message>
+        <message>
+            <source>BLSURF_TOPOLOGY_CAD</source>
+            <translation>From CAD</translation>
+        </message>
+        <message>
+            <source>BLSURF_TOPOLOGY_PROCESS</source>
+            <translation>Pre-process</translation>
+        </message>
+        <message>
+            <source>BLSURF_TOPOLOGY_PROCESS2</source>
+            <translation>Pre-process++</translation>
+        </message>
+        <message>
+            <source>BLSURF_VERBOSITY</source>
+            <translation>Verbosity level</translation>
+        </message>
+        <message>
+            <source>OBLIGATORY_VALUE</source>
+            <translation>(Obligatory value)</translation>
+        </message>
+        <message>
+            <source>OPTION_NAME_COLUMN</source>
+            <translation>Option</translation>
+        </message>
+        <message>
+            <source>OPTION_VALUE_COLUMN</source>
+            <translation>Value</translation>
+        </message>
+        <message>
+            <source>REMOVE_OPTION</source>
+            <translation>Clear option</translation>
+        </message>
         <message>
             <source>BLSURF_SIZE_MAP</source>
             <translation>Size Map</translation>
             <translation>Size on Point(s)</translation>
         </message>
         <message>
-            <source>BLSURF_ADV_ARGS</source>
-            <translation>Advanced</translation>
+            <source>BLSURF_ENF_VER</source>
+            <translation>Enforced vertices</translation>
         </message>
         <message>
-            <source>BLSURF_TITLE</source>
-            <translation>Hypothesis Construction</translation>
+            <source>BLSURF_ENF_VER_ENTRY_COLUMN</source>
+            <translation>Entry</translation>
         </message>
         <message>
-            <source>BLSURF_TOPOLOGY</source>
-            <translation>Topology</translation>
+            <source>BLSURF_ENF_VER_NAME_COLUMN</source>
+            <translation>Name</translation>
         </message>
         <message>
-            <source>BLSURF_TOPOLOGY_CAD</source>
-            <translation>From CAD</translation>
+            <source>BLSURF_ENF_VER_X_COLUMN</source>
+            <translation>X</translation>
         </message>
         <message>
-            <source>BLSURF_TOPOLOGY_PROCESS</source>
-            <translation>Pre-process</translation>
+            <source>BLSURF_ENF_VER_Y_COLUMN</source>
+            <translation>Y</translation>
         </message>
         <message>
-            <source>BLSURF_TOPOLOGY_PROCESS2</source>
-            <translation>Pre-process++</translation>
+            <source>BLSURF_ENF_VER_Z_COLUMN</source>
+            <translation>Z</translation>
         </message>
         <message>
-            <source>BLSURF_VERBOSITY</source>
-            <translation>Verbosity level</translation>
+            <source>BLSURF_ENF_VER_X_LABEL</source>
+            <translation>X:</translation>
         </message>
         <message>
-            <source>OBLIGATORY_VALUE</source>
-            <translation>(Obligatory value)</translation>
+            <source>BLSURF_ENF_VER_Y_LABEL</source>
+            <translation>Y:</translation>
         </message>
         <message>
-            <source>OPTION_NAME_COLUMN</source>
-            <translation>Option</translation>
+            <source>BLSURF_ENF_VER_Z_LABEL</source>
+            <translation>Z:</translation>
         </message>
         <message>
-            <source>OPTION_VALUE_COLUMN</source>
-            <translation>Value</translation>
+            <source>BLSURF_ENF_VER_VERTEX</source>
+            <translation>Add enforced vertex</translation>
         </message>
         <message>
-            <source>REMOVE_OPTION</source>
-            <translation>Clear option</translation>
+            <source>BLSURF_ENF_VER_REMOVE</source>
+            <translation>Remove vertex</translation>
         </message>
     </context>
 </TS>
index ebe8694a2c653860d402529de37dee14567e4f09..74a5f64c29509f4a0f0b78930d987f47719cbcad 100644 (file)
@@ -33,6 +33,7 @@
 #include <GEOM_Client.hxx>
 #include <SMESHGUI_Utils.h>
 #include <boost/shared_ptr.hpp>
+#include <GEOMImpl_Types.hxx>
 
 #include <TopoDS.hxx>
 #include <BRep_Tool.hxx>
@@ -195,71 +196,70 @@ std::string GeomSelectionTools::getFirstSelectedComponentDataType()
 }
 
 /*!
- *  Retrieve the TopoDS shape from the first selected object
- *  @return the TopoDS shape from the first selected object, empty TopoDS Shape if a shape is not selected.
+ * Retrieve the shape type from the entry
+ * @return the shape type from the entry, return TopAbs_SHAPE if the object does not define a shape or a group.
  */
-TopoDS_Shape GeomSelectionTools::getFirstSelectedTopoDSShape()
-{
- Handle(SALOME_InteractiveObject) anIO;
- anIO=GeomSelectionTools::getFirstSelectedSalomeObject();
- return entryToShape(anIO->getEntry());
-}
-
-/*!
- * Retrieve the TopoDS shape from the entry
- * @return the TopoDS shape from the entry, empty TopoDS Shape if the entry does not define a shape.
- */
-TopoDS_Shape GeomSelectionTools::entryToShape(std::string entry){
-  MESSAGE("GeomSelectionTools::entryToShape"<<entry );
+TopAbs_ShapeEnum GeomSelectionTools::entryToShapeType(std::string entry){
+//   MESSAGE("GeomSelectionTools::entryToShapeType"<<entry );
   TopoDS_Shape S = TopoDS_Shape();
+  TopAbs_ShapeEnum ShapeType = TopAbs_SHAPE;
    _PTR(SObject) aSO = myStudy->FindObjectID(entry);
   if (aSO){
     _PTR(SObject) aRefSObj;
     GEOM::GEOM_Object_var aShape;
-    MESSAGE("Got a SO");
+    // MESSAGE("Got a SO");
     // If selected object is a reference
     if ( aSO->ReferencedObject( aRefSObj ))
       aSO = aRefSObj;
-    MESSAGE("aSO->GetFatherComponent()->ComponentDataType(): " << aSO->GetFatherComponent()->ComponentDataType());
+    // MESSAGE("aSO->GetFatherComponent()->ComponentDataType(): " << aSO->GetFatherComponent()->ComponentDataType());
     if (  strcmp(aSO->GetFatherComponent()->ComponentDataType().c_str(),"GEOM") == 0)
       aShape = SMESH::SObjectToInterface<GEOM::GEOM_Object>(aSO);
     if ( !aShape->_is_nil() ){
-      MESSAGE("Got a Shape as Geom Object ");
-
-     SalomeApp_Application* anApp = GetSalomeApplication();
-     if (anApp) {
-       MESSAGE("Got Application");
-       Engines::Component_var component = anApp->lcc()->FindOrLoad_Component( "FactoryServer","GEOM" );
-       GEOM::GEOM_Gen_var _geomEngine = GEOM::GEOM_Gen::_narrow(component);
-       MESSAGE("Got GEOM engine");
-       GEOM_Client* aClient = new GEOM_Client();
-       if ( aClient && !_geomEngine->_is_nil() ) {
-         MESSAGE("GEOM client is OK and GEOM engine is not null");
-         S = aClient->GetShape( _geomEngine, aShape );
-       }
-     }
+      // MESSAGE("Got the Geom Object ");
+      // MESSAGE("Geom Object Type "<< aShape->GetType());
+      SalomeApp_Application* anApp = GetSalomeApplication();
+      if (anApp) {
+//         MESSAGE("Got Application");
+        Engines::Component_var component = anApp->lcc()->FindOrLoad_Component( "FactoryServer","GEOM" );
+        GEOM::GEOM_Gen_var _geomEngine = GEOM::GEOM_Gen::_narrow(component);
+//         MESSAGE("Got GEOM engine");
+        // if the Geom Object is a group
+        if (aShape->GetType() == GEOM_GROUP){
+//           MESSAGE("It's a group");  
+          GEOM::GEOM_IGroupOperations_var aGroupOp = _geomEngine->GetIGroupOperations(myStudy->StudyId());
+          ShapeType= (TopAbs_ShapeEnum)aGroupOp->GetType(aShape);
+        } 
+        // if not
+        else { 
+          GEOM_Client* aClient = new GEOM_Client();
+          if ( aClient && !_geomEngine->_is_nil() ) {
+//             MESSAGE("GEOM client is OK and GEOM engine is not null");
+            S = aClient->GetShape( _geomEngine, aShape );
+            ShapeType=S.ShapeType();
+          }
+        }
+      }
     }
   }
-  return S;
+//   MESSAGE("ShapeType returned is " << ShapeType);
+  return ShapeType;
 }
 
-
 /*!
  * Gives the ShapeType of the first Selected Object, return TopAbs_SHAPE if the first selected object does not define a shape.
  * @return the ShapeType of the first Selected Object, return TopAbs_SHAPE if the first selected object does not define a shape.
  */
 TopAbs_ShapeEnum GeomSelectionTools:: getFirstSelectedShapeType()
 {
- TopoDS_Shape S=getFirstSelectedTopoDSShape();
- if (!S.IsNull())
-   return S.ShapeType();
- else
-   return TopAbs_SHAPE;
+ Handle(SALOME_InteractiveObject) anIO;
+ anIO=GeomSelectionTools::getFirstSelectedSalomeObject();
+ return entryToShapeType(anIO->getEntry());
 }
 
 /*!
- *  Print information to std output of the face (if the first selected object is a face)
+ *  Print information to std output of the face
  *  and return the OCC type of face: Plane, Cylinder,Cone, Sphere, Torus, BezierSurface,BSplineSurface, SurfaceOfRevolution,SurfaceOfExtrusion, OtherSurface
+ *  @param TopoDS_Shape S Face we want information about.
  *  @return the OCC type of face: Plane, Cylinder,Cone, Sphere, Torus, BezierSurface,BSplineSurface, SurfaceOfRevolution,SurfaceOfExtrusion, OtherSurface
  *  return Other_Surface if the selected face is not a face.
  *  Information printed is :
@@ -269,9 +269,8 @@ TopAbs_ShapeEnum GeomSelectionTools:: getFirstSelectedShapeType()
  *  U or V is Rational ?
  *
  */
-GeomAbs_SurfaceType GeomSelectionTools::getFaceInformation()
+GeomAbs_SurfaceType GeomSelectionTools::getFaceInformation(TopoDS_Shape S)
 {
-  TopoDS_Shape S=getFirstSelectedTopoDSShape();
   GeomAbs_SurfaceType surf_type=GeomAbs_OtherSurface ;
   if (!S.IsNull() &&  S.ShapeType()==TopAbs_FACE){
     TopoDS_Face f=TopoDS::Face(S);
@@ -300,3 +299,4 @@ GeomAbs_SurfaceType GeomSelectionTools::getFaceInformation()
 
 
 
+
index 85c312d79269509c97efb22f5bb65588b431fc4a..2ec4e9f9d036953f748b5395deb40901fa82d464 100644 (file)
@@ -69,12 +69,12 @@ public:
   std::string getEntryOfObject(Handle(SALOME_InteractiveObject));
   std::string getNameFromEntry(std::string);
   std::string getFirstSelectedComponentDataType();
-  TopoDS_Shape getFirstSelectedTopoDSShape();
   TopAbs_ShapeEnum getFirstSelectedShapeType();
-  TopoDS_Shape entryToShape(std::string );
-  GeomAbs_SurfaceType getFaceInformation();
+  TopAbs_ShapeEnum entryToShapeType(std::string );
+  GeomAbs_SurfaceType getFaceInformation(TopoDS_Shape);
   _PTR(Study) getMyStudy();
 };
 
 
 #endif // _GEOMSELECTIONTOOLS_H_
+