Salome HOME
IPAL53870: Dump study script creates an excess sub-mesh
[modules/smesh.git] / src / SMESH_I / SMESH_NoteBook.cxx
index 7ecbe082382a2b20eb9677cdae5093d6a59c5810..4848a447a8155757ead6e087044bf503c09c4b9e 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -30,6 +30,9 @@
 #include <TColStd_SequenceOfAsciiString.hxx>
 #include <TColStd_HSequenceOfInteger.hxx>
 
+#include <SALOMEDS_wrap.hxx>
+#include <SALOMEDS_Attributes_wrap.hxx>
+
 #include <vector>
 #include <string>
 
@@ -50,7 +53,7 @@ namespace
    */
   void SetVariable(Handle(_pyCommand) theCommand,
                    const SMESH_ObjectStates* theStates,
-                   int position, int theArgNb)
+                   size_t position, int theArgNb)
   {
     if(theStates->GetCurrectState().size() > position)
       if(!theStates->GetCurrectState().at(position).IsEmpty())
@@ -97,7 +100,7 @@ void SMESH_ObjectStates::AddState(const TState &theState)
 //================================================================================
 TState SMESH_ObjectStates::GetCurrectState() const
 {
-  if(_states.size() > _dumpstate)
+  if ( (int) _states.size() > _dumpstate)
     return _states[_dumpstate];
   TState empty;
   return empty;
@@ -233,10 +236,11 @@ SMESH_NoteBook::~SMESH_NoteBook()
 //================================================================================
 void SMESH_NoteBook::ReplaceVariables()
 {
-  for(int i=0;i<_commands.size();i++) {
+  for ( size_t i = 0 ; i < _commands.size(); i++ )
+  {
     Handle(_pyCommand) aCmd = _commands[i];
-    TCollection_AsciiString aMethod = aCmd->GetMethod();
-    TCollection_AsciiString aObject = aCmd->GetObject();
+    TCollection_AsciiString aMethod      = aCmd->GetMethod();
+    TCollection_AsciiString aObject      = aCmd->GetObject();
     TCollection_AsciiString aResultValue = aCmd->GetResultValue();
     if(MYDEBUG) {
       cout<<"Command before : "<< aCmd->GetString()<<endl;
@@ -245,14 +249,74 @@ void SMESH_NoteBook::ReplaceVariables()
       cout<<"Result : "<< aResultValue<<endl;
     }
 
+    // NEW APPROACH
+    // Names of variables are stored in the Study, in "StringAttribute". Python commands
+    // store zero-based indices (as e.g.'$1$') of variables within "StringAttribute";
+    // An entry of object storing "StringAttribute" is at the end of the command
+    // after TVar::ObjPrefix().
+
+    // Get the entry of object storing "StringAttribute"
+    TCollection_AsciiString & cmdStr = aCmd->GetString();
+    TEntry2VarVecMap::iterator ent2varVec;
+    Standard_Integer fromIndex = 6;
+    Standard_Integer cmdLen = cmdStr.Length();
+    if ( int pos = (fromIndex <= cmdLen) ? cmdStr.Location( SMESH::TVar::ObjPrefix(), fromIndex, cmdLen ) : 0 )
+    {
+      TCollection_AsciiString varHolderEntry =
+        cmdStr.SubString( pos + strlen( SMESH::TVar::ObjPrefix() ), cmdLen );
+      ent2varVec = _entry2VarsMap.find( varHolderEntry );
+      cmdStr.Split( pos - 1 );
+    }
+    else
+    {
+      ent2varVec = _entry2VarsMap.find( aObject );
+    }
+    // Set variables in cmdStr
+    if ( ent2varVec != _entry2VarsMap.end() && !ent2varVec->second.empty() )
+    {
+      const std::vector< std::string >& vars = ent2varVec->second;
+      int pos = 1, pos2;
+      // look for '$VarIndex$' in cmdStr. TVar::Quote() == '$'
+      while (( pos  = cmdStr.Location( 1, SMESH::TVar::Quote(), pos,   cmdStr.Length() )) &&
+             ( pos2 = cmdStr.Location( 1, SMESH::TVar::Quote(), pos+1, cmdStr.Length() )) )
+      {
+        size_t varIndex = std::string::npos;
+        const char* varIndexPtr = cmdStr.ToCString() + pos;
+        if ( '0' <= *varIndexPtr && *varIndexPtr <= '9' )
+          varIndex = atoi( varIndexPtr );
+        if ( 0 <= varIndex && varIndex < vars.size() && !vars[varIndex].empty() )
+        {
+          // replace '$VarIndex$' either by var name of var value
+          const char var0    = vars[varIndex][0];
+          const bool isValue = (( '0' <= var0 && var0 <= '9' ) || var0 == '-');
+          if ( isValue ) // remove TVar::Quote() as well
+            pos2 += 2; // pos still points to '$'
+          int indexLen = pos2 - pos - 1;
+          int  lenDiff = int( vars[varIndex].size() ) - indexLen;
+          if      ( lenDiff > 0 )
+            cmdStr.InsertBefore( pos2, vars[varIndex].c_str() + vars[varIndex].size() - lenDiff );
+          else if ( lenDiff < 0 )
+            cmdStr.Remove( pos+1, -lenDiff );
+          cmdStr.SetValue( pos+(!isValue), vars[varIndex].c_str() );
+        }
+        pos = pos2 + 1;
+        if ( pos + 2 >= cmdStr.Length() )
+          break;
+      }
+    }
+
+    // OLD APPROACH
+    // Variable names are stored historically in "StringAttribute",
+    // i.e. for each command there is a set of either var names or separated empty places.
+
     // check if method modifies the object itself
     TVariablesMap::const_iterator it = _objectMap.find(aObject);
     if(it == _objectMap.end()) // check if method returns a new object
       it = _objectMap.find(aResultValue);
     
     if(it == _objectMap.end()) { // check if method modifies a mesh using mesh editor
-      TMeshEditorMap::const_iterator meIt = myMeshEditors.find(aObject);
-      if(meIt != myMeshEditors.end()) {
+      TMeshEditorMap::const_iterator meIt = _meshEditors.find(aObject);
+      if(meIt != _meshEditors.end()) {
         TCollection_AsciiString aMesh = (*meIt).second;
         it = _objectMap.find(aMesh);
       }
@@ -642,15 +706,15 @@ void SMESH_NoteBook::ReplaceVariables()
         // this (and above) code can work wrong since nb of states can differ from nb of
         // dumped calls due to the fix of
         // issue 0021364:: Dump of netgen parameters has duplicate lines
-        SMESH_Gen_i *aGen = SMESH_Gen_i::GetSMESHGen();
-        SALOMEDS::Study_ptr aStudy = aGen->GetCurrentStudy();
-        SALOMEDS::SObject_var sobj = aStudy->FindObjectID( (*it).first.ToCString() );
-        CORBA::Object_var      obj = aGen->SObjectToObject( sobj );
+        SMESH_Gen_i *          aGen = SMESH_Gen_i::GetSMESHGen();
+        SALOMEDS::Study_var  aStudy = aGen->GetCurrentStudy();
+        SALOMEDS::SObject_wrap sobj = aStudy->FindObjectID( (*it).first.ToCString() );
+        CORBA::Object_var       obj = aGen->SObjectToObject( sobj );
         if ( SMESH_Hypothesis_i* h = SMESH::DownCast< SMESH_Hypothesis_i*>( obj ))
         {
           TState aCurrentState = aStates->GetCurrectState();
-          int argIndex = h->getParamIndex( aMethod, aCurrentState.size() );
-          if ( 0 <= argIndex && argIndex < aCurrentState.size() &&
+          int         argIndex = h->getParamIndex( aMethod, aCurrentState.size() );
+          if ( 0 <= argIndex && argIndex < (int)aCurrentState.size() &&
                !aCurrentState[argIndex].IsEmpty() )
             aCmd->SetArg( 1, aCurrentState[argIndex] );
 
@@ -681,26 +745,32 @@ void SMESH_NoteBook::InitObjectMap()
   if(!aGen)
     return;
   
-  SALOMEDS::Study_ptr aStudy = aGen->GetCurrentStudy();
+  SALOMEDS::Study_var aStudy = aGen->GetCurrentStudy();
   if(aStudy->_is_nil())
     return;
   
-  SALOMEDS::SObject_var aSO = aStudy->FindComponent(aGen->ComponentDataType());
+  CORBA::String_var compDataType = aGen->ComponentDataType();
+  SALOMEDS::SObject_wrap     aSO = aStudy->FindComponent( compDataType.in() );
   if(CORBA::is_nil(aSO))
     return;
   
-  SALOMEDS::ChildIterator_var Itr = aStudy->NewChildIterator(aSO);
-  char* aParameters;
-  for(Itr->InitEx(true); Itr->More(); Itr->Next()) {
-    SALOMEDS::SObject_var aSObject = Itr->Value();
-    SALOMEDS::GenericAttribute_var anAttr;
-    if ( aSObject->FindAttribute(anAttr, "AttributeString")) {
-      aParameters = SALOMEDS::AttributeString::_narrow(anAttr)->Value();
-      SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
+  SALOMEDS::ChildIterator_wrap Itr = aStudy->NewChildIterator(aSO);
+  for( Itr->InitEx(true); Itr->More(); Itr->Next())
+  {
+    SALOMEDS::SObject_wrap aSObject = Itr->Value();
+    SALOMEDS::GenericAttribute_wrap anAttr;
+    if ( aSObject->FindAttribute( anAttr.inout(), "AttributeString"))
+    {
+      SALOMEDS::AttributeString_wrap strAttr = anAttr;
+      CORBA::String_var          aParameters = strAttr->Value();
+      CORBA::String_var                 anID = aSObject->GetID();
+      std::vector< std::string >     allVars = aGen->GetAllParameters( anID.in() );
+      SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters.in());
+      _entry2VarsMap[ TCollection_AsciiString( anID.in() )] = allVars;
       if(MYDEBUG) {
-        cout<<"Entry : "<< aSObject->GetID()<<endl;
+        cout<<"Entry : "<< anID<<endl;
         cout<<"aParameters : "<<aParameters<<endl;
-      }      
+      }
       TCollection_AsciiString anObjType;
       CORBA::Object_var       anObject = SMESH_Gen_i::SObjectToObject(aSObject);
       SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow(anObject);
@@ -718,12 +788,13 @@ void SMESH_NoteBook::InitObjectMap()
       if(anObjType == "LayerDistribution")
         aState = new LayerDistributionStates();
       else
-        aState = new  SMESH_ObjectStates(anObjType);
+        aState = new SMESH_ObjectStates(anObjType);
 
-      for(int i = 0; i < aSections->length(); i++) {
+      for ( size_t i = 0; i < aSections->length(); i++ ) {
         TState aVars;
         SALOMEDS::ListOfStrings aListOfVars = aSections[i];
-        for(int j = 0;j<aListOfVars.length();j++) {
+        for ( size_t j = 0; j < aListOfVars.length(); j++)
+        {
           TCollection_AsciiString aVar(aListOfVars[j].in());
           if(!aVar.IsEmpty() && aStudy->IsVariable(aVar.ToCString())) {
             aVar.InsertBefore(1,            SMESH::TVar::Quote() );
@@ -762,8 +833,8 @@ void SMESH_NoteBook::AddCommand(const TCollection_AsciiString& theString)
   _commands.push_back(aCommand);
 
   if ( aCommand->GetMethod() == "GetMeshEditor" ) { // MeshEditor creation
-    myMeshEditors.insert( make_pair( aCommand->GetResultValue(),
-                                     aCommand->GetObject() ) );
+    _meshEditors.insert( make_pair( aCommand->GetResultValue(),
+                                    aCommand->GetObject() ) );
   }
 }
 
@@ -788,8 +859,8 @@ void SMESH_NoteBook::ProcessLayerDistribution()
     return;
   
   // 2) Initialize all type of 1D Distribution hypothesis
-  for(int i=0;i<_commands.size();i++){
-    for(int j =0;j < aLDS.size();j++){
+  for ( size_t i = 0; i < _commands.size(); i++ ) {
+    for ( size_t j = 0; j < aLDS.size(); j++ ) {
       TCollection_AsciiString aResultValue = _commands[i]->GetResultValue();
       if(_commands[i]->GetMethod() == "CreateHypothesis" &&
          aLDS[j]->HasDistribution(aResultValue)){
@@ -801,8 +872,8 @@ void SMESH_NoteBook::ProcessLayerDistribution()
   }
   // 3) ... and replase variables ...
 
-  for(int i=0;i<_commands.size();i++){
-    for(int j =0;j < aLDS.size();j++){
+  for ( size_t i = 0; i < _commands.size(); i++ ) {
+    for ( size_t j = 0; j < aLDS.size(); j++ ) {
       TCollection_AsciiString anObject = _commands[i]->GetObject();
 
       if(aLDS[j]->HasDistribution(anObject)) {
@@ -858,11 +929,22 @@ void SMESH_NoteBook::ProcessLayerDistribution()
 TCollection_AsciiString SMESH_NoteBook::GetResultScript() const
 {
   TCollection_AsciiString aResult;
-  for(int i=0;i<_commands.size();i++)
-    aResult+=_commands[i]->GetString()+"\n";
+  for ( size_t i = 0; i < _commands.size(); i++ )
+    aResult += _commands[i]->GetString() + "\n";
   return aResult;
 }
 
+//================================================================================
+/*!
+ *  \brief Return lines of the result script
+ */
+//================================================================================
+void SMESH_NoteBook::GetResultLines(std::list< TCollection_AsciiString >& lines) const
+{
+  for ( size_t i = 0; i < _commands.size(); i++ )
+    lines.push_back( _commands[i]->GetString() );
+}
+
 //================================================================================
 /*!
  *  \brief Return value of the variable
@@ -888,10 +970,9 @@ bool SMESH_NoteBook::GetReal(const TCollection_AsciiString& theVarName, double&
 
   const char* aName = aVarName.ToCString();
   if(aStudy->IsVariable(aName) && (aStudy->IsReal(aName) || aStudy->IsInteger(aName))) {
-    theValue = aStudy->GetReal(aVarName.ToCString());
+    theValue = aStudy->GetReal(aName);
     ok = true;
   }
 
   return ok;
 }
-