Salome HOME
PR: synchro V6_main tag mergeto_V7_main_11Feb13
[modules/smesh.git] / src / SMESH_I / SMESH_2smeshpy.cxx
index a2f526ddb80ea70944f922fba6020d399631b1ee..57a076883f6fa04f107a99bd22e86be21a89fd85 100644 (file)
 //
 #include "SMESH_2smeshpy.hxx"
 
-#include "utilities.h"
 #include "SMESH_PythonDump.hxx"
 #include "SMESH_NoteBook.hxx"
 #include "SMESH_Filter_i.hxx"
 
+#include <SALOMEDS_wrap.hxx>
+#include <utilities.h>
+
 #include <Resource_DataMapOfAsciiStringAsciiString.hxx>
 #include <Resource_DataMapIteratorOfDataMapOfAsciiStringAsciiString.hxx>
 
@@ -124,6 +126,31 @@ namespace {
     }
   };
 
+  //================================================================================
+  /*!
+   * \brief Map of TCollection_AsciiString initialized by C array of C strings.
+   *        Odd items of the C array are map keys, and even items are values
+   */
+  //================================================================================
+
+  struct TStringMap: public map<TCollection_AsciiString,TCollection_AsciiString>
+  {
+    /*!
+     * \brief Filling. The last string must be ""
+     */
+    void Insert(const char* names_values[]) {
+      for ( int i = 0; names_values[i][0] ; i += 2 )
+        insert( make_pair( (char*) names_values[i], names_values[i+1] ));
+    }
+    /*!
+     * \brief Check if a string is in
+     */
+    TCollection_AsciiString Value(const TCollection_AsciiString& name ) {
+      map< _AString, _AString >::iterator it = find( name );
+      return it == end() ? "" : it->second;
+    }
+  };
+
   //================================================================================
   /*!
    * \brief Returns a mesh by object
@@ -406,7 +433,7 @@ _pyGen::_pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod
   {
     // find a GEOM entry
     _pyID geomID;
-    SALOMEDS::SComponent_var geomComp = theStudy->FindComponent("GEOM");
+    SALOMEDS::SComponent_wrap geomComp = theStudy->FindComponent("GEOM");
     if ( geomComp->_is_nil() ) return;
     CORBA::String_var entry = geomComp->GetID();
     geomID = entry.in();
@@ -533,10 +560,14 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
       groups = aCommand->GetResultValue(2);
     else if ( method == "MakeBoundaryElements")
       groups = aCommand->GetResultValue(3);
+    else if ( method == "Create0DElementsOnAllNodes" &&
+              aCommand->GetArg(2).Length() > 2 ) // group name != ''
+      groups = aCommand->GetResultValue();
 
     id_editor->second->Process( aCommand );
     id_editor->second->AddProcessedCmd( aCommand );
 
+    // create meshes
     if ( !meshID.IsEmpty() &&
          !myMeshes.count( meshID ) &&
          aCommand->IsStudyEntry( meshID ))
@@ -547,6 +578,7 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
       aCommand->Clear();
       aCommand->GetString() = processedCommand; // discard changes made by _pyMesh
     }
+    // create groups
     if ( !groups.IsEmpty() )
     {
       if ( !aCommand->IsStudyEntry( meshID ))
@@ -730,7 +762,9 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
     myMeshes.insert( make_pair( mesh->GetID(), mesh ));
     return;
   }
-  if( method == "CreateMeshesFromMED" || method == "CreateMeshesFromSAUV")
+  if( method == "CreateMeshesFromMED" ||
+      method == "CreateMeshesFromSAUV"||
+      method == "CreateMeshesFromGMF" )
   {
     for(int ind = 0;ind<theCommand->GetNbResultValues();ind++)
     {
@@ -786,7 +820,7 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
     }
   }
 
-  // objects erasing creation command if no more it's commands invoked:
+  // objects erasing creation command if no more its commands invoked:
   // SMESH_Pattern, FilterManager
   if ( method == "GetPattern" ||
        method == "CreateFilterManager" ||
@@ -1297,7 +1331,7 @@ bool _pyGen::IsNotPublished(const _pyID& theObjID) const
   // either the SMESH object is not in study or it is a GEOM object
   if ( IsGeomObject( theObjID ))
   {
-    SALOMEDS::SObject_var so = myStudy->FindObjectID( theObjID.ToCString() );
+    SALOMEDS::SObject_wrap so = myStudy->FindObjectID( theObjID.ToCString() );
     if ( so->_is_nil() ) return true;
     CORBA::Object_var obj = so->GetObject();
     return CORBA::is_nil( obj );
@@ -1503,6 +1537,33 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
     myGroups.push_back( group );
     theGen->AddObject( group );
   }
+  // update list of groups
+  else if ( method == "GetGroups" )
+  {
+    TCollection_AsciiString grIDs = theCommand->GetResultValue();
+    list< _pyID > idList = theCommand->GetStudyEntries( grIDs );
+    list< _pyID >::iterator grID = idList.begin();
+    for ( ; grID != idList.end(); ++grID )
+    {
+      Handle(_pyObject) obj = theGen->FindObject( *grID );
+      if ( obj.IsNull() )
+      {
+        Handle(_pyGroup) group = new _pyGroup( theCommand, *grID );
+        theGen->AddObject( group );
+        myGroups.push_back( group );
+      }
+    }
+  }
+  // notify a group about full removal
+  else if ( method == "RemoveGroupWithContents" )
+  {
+    if ( !theGen->IsToKeepAllCommands() ) { // snapshot mode
+      const _pyID groupID = theCommand->GetArg( 1 );
+      Handle(_pyGroup) grp = Handle(_pyGroup)::DownCast( theGen->FindObject( groupID ));
+      if ( !grp.IsNull() )
+        grp->RemovedWithContents();
+    }
+  }
   // ----------------------------------------------------------------------
   else if ( theCommand->MethodStartsFrom( "Export" ))
   {
@@ -1510,7 +1571,7 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
          method == "ExportToMEDX" ) { // ExportToMEDX() --> ExportMED()
       theCommand->SetMethod( "ExportMED" );
     }
-    else if ( method == "ExportCGNS" )
+    else if ( method == "ExportCGNS" || method == "ExportGMF" )
     { // ExportCGNS(part, ...) -> ExportCGNS(..., part)
       _pyID partID = theCommand->GetArg( 1 );
       int nbArgs = theCommand->GetNbArgs();
@@ -1539,26 +1600,44 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
   // ----------------------------------------------------------------------
   else if ( method == "RemoveHypothesis" ) // (geom, hyp)
   {
-    _pyID hypID = theCommand->GetArg( 2 );
+    _pyID hypID  = theCommand->GetArg( 2 );
+    _pyID geomID = theCommand->GetArg( 1 );
+    bool isLocal = ( geomID != GetGeom() );
 
     // check if this mesh still has corresponding addition command
-    bool hasAddCmd = false;
-    list< Handle(_pyCommand) >::iterator cmd = myAddHypCmds.begin();
-    while ( cmd != myAddHypCmds.end() )
+    Handle(_pyCommand) addCmd;
+    list< Handle(_pyCommand) >::iterator cmd;
+    list< Handle(_pyCommand) >* addCmds[2] = { &myAddHypCmds, &myNotConvertedAddHypCmds };
+    for ( int i = 0; i < 2; ++i )
     {
-      // AddHypothesis(geom, hyp)
-      if ( hypID == (*cmd)->GetArg( 2 )) { // erase both (add and remove) commands
-        theCommand->Clear();
-        (*cmd)->Clear();
-        cmd = myAddHypCmds.erase( cmd );
-        hasAddCmd = true;
-      }
-      else {
-        ++cmd;
+      list< Handle(_pyCommand )> & addHypCmds = *(addCmds[i]);
+      for ( cmd = addHypCmds.begin(); cmd != addHypCmds.end(); )
+      {
+        bool sameHyp = true;
+        if ( hypID != (*cmd)->GetArg( 1 ) && hypID != (*cmd)->GetArg( 2 ))
+          sameHyp = false; // other hyp
+        if ( (*cmd)->GetNbArgs() == 2 &&
+             geomID != (*cmd)->GetArg( 1 ) && geomID != (*cmd)->GetArg( 2 ))
+          sameHyp = false; // other geom
+        if ( (*cmd)->GetNbArgs() == 1 && isLocal )
+          sameHyp = false; // other geom
+        if ( sameHyp )
+        {
+          addCmd = *cmd;
+          cmd    = addHypCmds.erase( cmd );
+          if ( !theGen->IsToKeepAllCommands() ) {
+            addCmd->Clear();
+            theCommand->Clear();
+          }
+        }
+        else
+        {
+          ++cmd;
+        }
       }
     }
     Handle(_pyHypothesis) hyp = theGen->FindHyp( hypID );
-    if ( ! hasAddCmd && hypID.Length() != 0 ) { // hypo addition already wrapped
+    if ( !theCommand->IsEmpty() && !hypID.IsEmpty() ) {
       // RemoveHypothesis(geom, hyp) --> RemoveHypothesis( hyp, geom=0 )
       _pyID geom = theCommand->GetArg( 1 );
       theCommand->RemoveArgs();
@@ -1586,23 +1665,6 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
         subMesh->Process( theCommand ); // it moves GetSubMesh() before theCommand
     }
   }
-  // update list of groups
-  else if ( method == "GetGroups" )
-  {
-    TCollection_AsciiString grIDs = theCommand->GetResultValue();
-    list< _pyID > idList = theCommand->GetStudyEntries( grIDs );
-    list< _pyID >::iterator grID = idList.begin();
-    for ( ; grID != idList.end(); ++grID )
-    {
-      Handle(_pyObject) obj = theGen->FindObject( *grID );
-      if ( obj.IsNull() )
-      {
-        Handle(_pyGroup) group = new _pyGroup( theCommand, *grID );
-        theGen->AddObject( group );
-        myGroups.push_back( group );
-      }
-    }
-  }
   // add accessor method if necessary
   else
   {
@@ -1740,6 +1802,7 @@ void _pyMesh::Flush()
       addCmd->SetArg( 1, algoID );
       if ( isLocalAlgo )
         addCmd->SetArg( 2, geom );
+      myNotConvertedAddHypCmds.push_back( addCmd );
     }
   }
 
@@ -1760,6 +1823,7 @@ void _pyMesh::Flush()
       addCmd->SetArg( 1, hypID );
       if ( geom != GetGeom() )
         addCmd->SetArg( 2, geom );
+      myNotConvertedAddHypCmds.push_back( addCmd );
     }
   }
 
@@ -1909,14 +1973,15 @@ _pyMeshEditor::_pyMeshEditor(const Handle(_pyCommand)& theCreationCmd):
 
 void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
 {
-  // names of SMESH_MeshEditor methods fully equal to methods of python class Mesh, so
-  // commands calling this methods are converted to calls of methods of Mesh
+  // names of SMESH_MeshEditor methods fully equal to methods of the python class Mesh, so
+  // commands calling this methods are converted to calls of Mesh methods
   static TStringSet sameMethods;
   if ( sameMethods.empty() ) {
     const char * names[] = {
       "RemoveElements","RemoveNodes","RemoveOrphanNodes","AddNode","Add0DElement","AddEdge","AddFace","AddPolygonalFace","AddBall",
       "AddVolume","AddPolyhedralVolume","AddPolyhedralVolumeByFaces","MoveNode", "MoveClosestNodeToPoint",
-      "InverseDiag","DeleteDiag","Reorient","ReorientObject","TriToQuad","SplitQuad","SplitQuadObject",
+      "InverseDiag","DeleteDiag","Reorient","ReorientObject",
+      "TriToQuad","TriToQuadObject", "SplitQuad","SplitQuadObject",
       "BestSplit","Smooth","SmoothObject","SmoothParametric","SmoothParametricObject",
       "ConvertToQuadratic","ConvertFromQuadratic","RenumberNodes","RenumberElements",
       "RotationSweep","RotationSweepObject","RotationSweepObject1D","RotationSweepObject2D",
@@ -1930,12 +1995,26 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
       "GetLastCreatedElems",
       "MirrorMakeMesh","MirrorObjectMakeMesh","TranslateMakeMesh",
       "TranslateObjectMakeMesh","RotateMakeMesh","RotateObjectMakeMesh","MakeBoundaryMesh",
-      "MakeBoundaryElements"
+      "MakeBoundaryElements", "SplitVolumesIntoTetra"
       ,"" }; // <- mark of the end
     sameMethods.Insert( names );
   }
 
-  // names of SMESH_MeshEditor methods which differ from methods of class Mesh
+  // names of SMESH_MeshEditor commands in which only a method name must be replaced
+  TStringMap diffMethods;
+  if ( diffMethods.empty() ) {
+    const char * orig2newName[] = {
+      // original name --------------> new name
+      "ExtrusionAlongPathObjX"      , "ExtrusionAlongPathX",
+      "FindCoincidentNodesOnPartBut", "FindCoincidentNodesOnPart",
+      "ConvertToQuadraticObject"    , "ConvertToQuadratic",
+      "ConvertFromQuadraticObject"  , "ConvertFromQuadratic",
+      "Create0DElementsOnAllNodes"  , "Add0DElementsToAllNodes",
+      ""};// <- mark of the end
+    diffMethods.Insert( orig2newName );
+  }
+
+  // names of SMESH_MeshEditor methods which differ from methods of Mesh class
   // only by last two arguments
   static TStringSet diffLastTwoArgsMethods;
   if (diffLastTwoArgsMethods.empty() ) {
@@ -1947,13 +2026,21 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
     diffLastTwoArgsMethods.Insert( names );
   }
 
+  // only a method name is to change?
   const TCollection_AsciiString & method = theCommand->GetMethod();
   bool isPyMeshMethod = sameMethods.Contains( method );
   if ( !isPyMeshMethod )
   {
-    //Replace SMESH_MeshEditor "MakeGroups" functions by the Mesh
-    //functions with the flag "theMakeGroups = True" like:
-    //SMESH_MeshEditor.CmdMakeGroups => Mesh.Cmd(...,True)
+    TCollection_AsciiString newMethod = diffMethods.Value( method );
+    if (( isPyMeshMethod = ( newMethod.Length() > 0 )))
+      theCommand->SetMethod( newMethod );
+  }
+
+  if ( !isPyMeshMethod )
+  {
+    // Replace SMESH_MeshEditor "*MakeGroups" functions by the Mesh
+    // functions with the flag "theMakeGroups = True" like:
+    // SMESH_MeshEditor.CmdMakeGroups => Mesh.Cmd(...,True)
     int pos = method.Search("MakeGroups");
     if( pos != -1)
     {
@@ -1978,7 +2065,7 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
     }
   }
 
-  // ExtrusionSweep0D() -> ExtrusionSweep()
+  // ExtrusionSweep0D()       -> ExtrusionSweep()
   // ExtrusionSweepObject0D() -> ExtrusionSweepObject()
   if ( !isPyMeshMethod && ( method == "ExtrusionSweep0D"  ||
                             method == "ExtrusionSweepObject0D" ))
@@ -1988,19 +2075,7 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
     theCommand->SetArg(theCommand->GetNbArgs()+1,"False");  //sets flag "MakeGroups = False"
     theCommand->SetArg(theCommand->GetNbArgs()+1,"True");  //sets flag "IsNode = True"
   }
-  // set "ExtrusionAlongPathX()" instead of "ExtrusionAlongPathObjX()"
-  if ( !isPyMeshMethod && method == "ExtrusionAlongPathObjX")
-  {
-    isPyMeshMethod = true;
-    theCommand->SetMethod("ExtrusionAlongPathX");
-  }
 
-  // set "FindCoincidentNodesOnPart()" instead of "FindCoincidentNodesOnPartBut()"
-  if ( !isPyMeshMethod && method == "FindCoincidentNodesOnPartBut")
-  {
-    isPyMeshMethod = true;
-    theCommand->SetMethod("FindCoincidentNodesOnPart");
-  }
   // DoubleNode...New(...) -> DoubleNode...(...,True)
   if ( !isPyMeshMethod && ( method == "DoubleNodeElemGroupNew"  ||
                             method == "DoubleNodeElemGroupsNew" ||
@@ -2025,14 +2100,6 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
       theCommand->SetResultValue( groupID );
     }
   }
-  // ConvertToQuadraticObject(bool,obj) -> ConvertToQuadratic(bool,obj)
-  // ConvertFromQuadraticObject(obj) -> ConvertFromQuadratic(obj)
-  if ( !isPyMeshMethod && ( method == "ConvertToQuadraticObject" ||
-                            method == "ConvertFromQuadraticObject" ))
-  {
-    isPyMeshMethod = true;
-    theCommand->SetMethod( method.SubString( 1, method.Length()-6));
-  }
   // FindAmongElementsByPoint(meshPart, x, y, z, elementType) ->
   // FindElementsByPoint(x, y, z, elementType, meshPart)
   if ( !isPyMeshMethod && method == "FindAmongElementsByPoint" )
@@ -2063,10 +2130,15 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
       theCommand->SetArg( 3, face );
   }
 
-  // meshes made by *MakeMesh() methods are not wrapped by _pyMesh,
-  // so let _pyMesh care of it (TMP?)
-  //     if ( theCommand->GetMethod().Search("MakeMesh") != -1 )
-  //       _pyMesh( new _pyCommand( theCommand->GetString(), 0 )); // for theGen->SetAccessorMethod()
+  if ( method == "QuadToTri" || method == "QuadToTriObject" )
+  {
+    isPyMeshMethod = true;
+    int crit_arg = theCommand->GetNbArgs();
+    const _AString& crit = theCommand->GetArg(crit_arg);
+    if (crit.Search("MaxElementLength2D") != -1)
+      theCommand->SetArg(crit_arg, "");
+  }
+
   if ( isPyMeshMethod )
   {
     theCommand->SetObject( myMesh );
@@ -2074,7 +2146,7 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
   else
   {
     // editor creation command is needed only if any editor function is called
-    theGen->AddMeshAccessorMethod( theCommand ); // for *Object()
+    theGen->AddMeshAccessorMethod( theCommand ); // for *Object() methods
     if ( !myCreationCmdStr.IsEmpty() ) {
       GetCreationCmd()->GetString() = myCreationCmdStr;
       myCreationCmdStr.Clear();
@@ -2356,7 +2428,7 @@ void _pyHypothesis::Assign( const Handle(_pyHypothesis)& theOther,
   myGeom                    = theOther->myGeom;
   myMesh                    = theMesh;
   myAlgoType2CreationMethod = theOther->myAlgoType2CreationMethod;
-  //myArgCommands             = theOther->myArgCommands;
+  myAccumulativeMethods     = theOther->myAccumulativeMethods;
   //myUnusedCommands          = theOther->myUnusedCommands;
   // init myCurCrMethod
   GetCreationMethod( theOther->GetAlgoType() );
@@ -2485,7 +2557,9 @@ bool _pyHypothesis::GetReferredMeshesAndGeom( list< Handle(_pyMesh) >& meshes )
 void _pyHypothesis::rememberCmdOfParameter( const Handle(_pyCommand) & theCommand )
 {
   // parameters are discriminated by method name
-  TCollection_AsciiString method = theCommand->GetMethod();
+  _AString method = theCommand->GetMethod();
+  if ( myAccumulativeMethods.count( method ))
+    return; // this method adds values and not override the previus value
 
   // discriminate commands setting different parameters via one method
   // by passing parameter names like e.g. SetOption("size", "0.2")
@@ -2503,7 +2577,7 @@ void _pyHypothesis::rememberCmdOfParameter( const Handle(_pyCommand) & theComman
     }
   }
   // parameters are discriminated by method name
-  list< Handle(_pyCommand)>& cmds = myMeth2Commands[ theCommand->GetMethod() ];
+  list< Handle(_pyCommand)>& cmds = myMeth2Commands[ method /*theCommand->GetMethod()*/ ];
   if ( !cmds.empty() && !isCmdUsedForCompute( cmds.back() ))
   {
     cmds.back()->Clear(); // previous parameter value has not been used
@@ -3304,10 +3378,10 @@ static inline bool isWord(const char c, const bool dotIsWord)
  */
 //================================================================================
 
-TCollection_AsciiString _pyCommand::GetWord( const TCollection_AsciiString & theString,
-                                            int &      theStartPos,
-                                            const bool theForward,
-                                            const bool dotIsWord )
+TCollection_AsciiString _pyCommand::GetWord( const _AString & theString,
+                                             int &            theStartPos,
+                                             const bool       theForward,
+                                             const bool       dotIsWord )
 {
   int beg = theStartPos, end = theStartPos;
   theStartPos = EMPTY;
@@ -3744,7 +3818,7 @@ bool _pySubMesh::CanBeArgOfMethod(const _AString& theMethodName)
       "TranslateObjectMakeGroups","TranslateObjectMakeMesh","ScaleMakeGroups","ScaleMakeMesh",
       "RotateObject","RotateObjectMakeGroups","RotateObjectMakeMesh","FindCoincidentNodesOnPart",
       "FindCoincidentNodesOnPartBut","FindEqualElements","FindAmongElementsByPoint",
-      "MakeBoundaryMesh",
+      "MakeBoundaryMesh","Create0DElementsOnAllNodes",
       "" }; // <- mark of end
     methods.Insert( names );
   }
@@ -3842,6 +3916,21 @@ _pyGroup::_pyGroup(const Handle(_pyCommand)& theCreationCmd, const _pyID & id)
   }
 }
 
+//================================================================================
+/*!
+ * \brief set myCanClearCreationCmd = true if the main action of the creation
+ *        command is discarded
+ */
+//================================================================================
+
+void _pyGroup::RemovedWithContents()
+{
+  // this code would be appropriate if Add0DElementsToAllNodes() returned only new nodes
+  // via a created group
+  //if ( GetCreationCmd()->GetMethod() == "Add0DElementsToAllNodes")
+  // myCanClearCreationCmd = true;
+}
+
 //================================================================================
 /*!
  * \brief To convert creation of a group by filter
@@ -3919,8 +4008,6 @@ void _pyGroup::Process( const Handle(_pyCommand)& theCommand)
 //================================================================================
 /*!
  * \brief Prevent clearing "DoubleNode...() command if a group created by it is removed
- * 
- * 
  */
 //================================================================================
 
@@ -4023,73 +4110,8 @@ bool _pyFilter::CanClear()
 
 _pyHypothesisReader::_pyHypothesisReader()
 {
-  // Get paths to xml files of plugins
-  vector< string > xmlPaths;
-  string sep;
-  if ( const char* meshersList = getenv("SMESH_MeshersList") )
-  {
-    string meshers = meshersList, plugin;
-    string::size_type from = 0, pos;
-    while ( from < meshers.size() )
-    {
-      // cut off plugin name
-      pos = meshers.find( ':', from );
-      if ( pos != string::npos )
-        plugin = meshers.substr( from, pos-from );
-      else
-        plugin = meshers.substr( from ), pos = meshers.size();
-      from = pos + 1;
-
-      // get PLUGIN_ROOT_DIR path
-      string rootDirVar, pluginSubDir = plugin;
-      if ( plugin == "StdMeshers" )
-        rootDirVar = "SMESH", pluginSubDir = "smesh";
-      else
-        for ( pos = 0; pos < plugin.size(); ++pos )
-          rootDirVar += toupper( plugin[pos] );
-      rootDirVar += "_ROOT_DIR";
-
-      const char* rootDir = getenv( rootDirVar.c_str() );
-      if ( !rootDir || strlen(rootDir) == 0 )
-      {
-        rootDirVar = plugin + "_ROOT_DIR"; // HexoticPLUGIN_ROOT_DIR
-        rootDir = getenv( rootDirVar.c_str() );
-        if ( !rootDir || strlen(rootDir) == 0 ) continue;
-      }
-
-      // get a separator from rootDir
-      for ( pos = strlen( rootDir )-1; pos >= 0 && sep.empty(); --pos )
-        if ( rootDir[pos] == '/' || rootDir[pos] == '\\' )
-        {
-          sep = rootDir[pos];
-          break;
-        }
-#ifdef WNT
-      if (sep.empty() ) sep = "\\";
-#else
-      if (sep.empty() ) sep = "/";
-#endif
-
-      // get a path to resource file
-      string xmlPath = rootDir;
-      if ( xmlPath[ xmlPath.size()-1 ] != sep[0] )
-        xmlPath += sep;
-      xmlPath += "share" + sep + "salome" + sep + "resources" + sep;
-      for ( pos = 0; pos < pluginSubDir.size(); ++pos )
-        xmlPath += tolower( pluginSubDir[pos] );
-      xmlPath += sep + plugin + ".xml";
-      bool fileOK;
-#ifdef WNT
-      fileOK = (GetFileAttributes(xmlPath.c_str()) != INVALID_FILE_ATTRIBUTES);
-#else
-      fileOK = (access(xmlPath.c_str(), F_OK) == 0);
-#endif
-      if ( fileOK )
-        xmlPaths.push_back( xmlPath );
-    }
-  }
-
   // Read xml files
+  vector< string > xmlPaths = SMESH_Gen::GetPluginXMLPaths();
   LDOMParser xmlParser;
   for ( size_t i = 0; i < xmlPaths.size(); ++i )
   {
@@ -4111,7 +4133,7 @@ _pyHypothesisReader::_pyHypothesisReader()
     LDOM_NodeList algoNodeList = xmlDoc.getElementsByTagName( "algorithm" );
     for ( int i = 0; i < algoNodeList.getLength(); ++i )
     {
-      LDOM_Node algoNode = algoNodeList.item( i );
+      LDOM_Node     algoNode = algoNodeList.item( i );
       LDOM_Element& algoElem = (LDOM_Element&) algoNode;
       LDOM_NodeList pyAlgoNodeList = algoElem.getElementsByTagName( "algo" );
       if ( pyAlgoNodeList.getLength() < 1 ) continue;
@@ -4173,7 +4195,43 @@ _pyHypothesisReader::_pyHypothesisReader()
         }
       }
     }
-  }
+    // <hypothesis type="BLSURF_Parameters"
+    //          ...
+    //          dim="2">
+    //   <python-wrap>
+    //     <accumulative-methods> 
+    //       SetEnforcedVertex,
+    //       SetEnforcedVertexNamed
+    //     </accumulative-methods>
+    //   </python-wrap>
+    // </hypothesis>
+    //
+    LDOM_NodeList hypNodeList = xmlDoc.getElementsByTagName( "hypothesis" );
+    for ( int i = 0; i < hypNodeList.getLength(); ++i )
+    {
+      LDOM_Node     hypNode      = hypNodeList.item( i );
+      LDOM_Element& hypElem      = (LDOM_Element&) hypNode;
+      _AString      hypType      = hypElem.getAttribute("type");
+      LDOM_NodeList methNodeList = hypElem.getElementsByTagName( "accumulative-methods" );
+      if ( methNodeList.getLength() != 1 || hypType.IsEmpty() ) continue;
+
+      map<_AString, Handle(_pyHypothesis)>::const_iterator type2hyp = myType2Hyp.find( hypType );
+      if ( type2hyp == myType2Hyp.end() ) continue;
+
+      LDOM_Node methNode = methNodeList.item( 0 );
+      LDOM_Node textNode = methNode.getFirstChild();
+      _AString      text = textNode.getNodeValue();
+      _AString method;
+      int pos = 1;
+      do {
+        method = _pyCommand::GetWord( text, pos, /*forward= */true );
+        pos += method.Length();
+        type2hyp->second->AddAccumulativeMethod( method );
+      }
+      while ( !method.IsEmpty() );
+    }
+
+  } // loop on xmlPaths
 }
 
 //================================================================================