Salome HOME
Fix to avoid dependence of mesh on itself (it leaded to cycle in 'SetRemovedFromStudy').
[modules/smesh.git] / src / SMESH_I / SMESH_2smeshpy.cxx
index 5b10f99146c7cc79f79a2cc5e9ee063eb9fc5381..20cc26043e36127d0f88380b1313a36392ec0def 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -179,6 +179,24 @@ namespace {
 
   void CheckObjectPresence( const Handle(_pyCommand)& cmd, set<_pyID> & presentObjects)
   {
+    // either comment or erase a command including NotPublishedObjectName()
+    if ( cmd->GetString().Location( TPythonDump::NotPublishedObjectName(), 1, cmd->Length() ))
+    {
+      bool isResultPublished = false;
+      for ( int i = 0; i < cmd->GetNbResultValues(); i++ )
+      {
+        _pyID objID = cmd->GetResultValue( i+1 );
+        if ( cmd->IsStudyEntry( objID ))
+          isResultPublished = (! theGen->IsNotPublished( objID ));
+        theGen->ObjectCreationRemoved( objID ); // objID.SetName( name ) is not needed
+      }
+      if ( isResultPublished )
+        cmd->Comment();
+      else
+        cmd->Clear();
+      return;
+    }
+    // comment a command having not created args
     for ( int iArg = cmd->GetNbArgs(); iArg; --iArg )
     {
       const _pyID& arg = cmd->GetArg( iArg );
@@ -192,14 +210,23 @@ namespace {
           cmd->Comment();
           cmd->GetString() += " ### " ;
           cmd->GetString() += *id + " has not been yet created";
+          for ( int i = 0; i < cmd->GetNbResultValues(); i++ ) {
+            _pyID objID = cmd->GetResultValue( i+1 );
+            theGen->ObjectCreationRemoved( objID ); // objID.SetName( name ) is not needed
+          }
           return;
         }
     }
+    // comment a command having not created Object
     const _pyID& obj = cmd->GetObject();
     if ( !obj.IsEmpty() && cmd->IsStudyEntry( obj ) && !presentObjects.count( obj ))
     {
       cmd->Comment();
       cmd->GetString() += " ### not created object" ;
+      for ( int i = 0; i < cmd->GetNbResultValues(); i++ ) {
+        _pyID objID = cmd->GetResultValue( i+1 );
+        theGen->ObjectCreationRemoved( objID ); // objID.SetName( name ) is not needed
+      }
     }
     const _pyID& result = cmd->GetResultValue();
     if ( result.IsEmpty() || result.Value( 1 ) == '"' || result.Value( 1 ) == '\'' )
@@ -318,13 +345,15 @@ namespace {
 
 //================================================================================
 /*!
- * \brief Convert python script using commands of smesh.py
-  * \param theScript - Input script
-  * \retval TCollection_AsciiString - Convertion result
-  * \param theToKeepAllCommands - to keep all commands or
-  *        to exclude commands relating to objects removed from study
-  *
-  * Class SMESH_2smeshpy declared in SMESH_PythonDump.hxx
+ * \brief Convert a python script using commands of smeshBuilder.py
+ *  \param theScript - Input script
+ *  \param theEntry2AccessorMethod - returns method names to access to
+ *         objects wrapped with python class
+ *  \param theObjectNames - names of objects
+ *  \param theRemovedObjIDs - entries of objects whose created commands were removed
+ *  \param theHistoricalDump - true means to keep all commands, false means
+ *         to exclude commands relating to objects removed from study
+ *  \retval TCollection_AsciiString - Convertion result
  */
 //================================================================================
 
@@ -332,10 +361,15 @@ TCollection_AsciiString
 SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString&            theScript,
                               Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod,
                               Resource_DataMapOfAsciiStringAsciiString& theObjectNames,
+                              std::set< TCollection_AsciiString >&      theRemovedObjIDs,
                               SALOMEDS::Study_ptr&                      theStudy,
                               const bool                                theToKeepAllCommands)
 {
-  theGen = new _pyGen( theEntry2AccessorMethod, theObjectNames, theStudy, theToKeepAllCommands );
+  theGen = new _pyGen( theEntry2AccessorMethod,
+                       theObjectNames,
+                       theRemovedObjIDs,
+                       theStudy,
+                       theToKeepAllCommands );
 
   // split theScript into separate commands
 
@@ -345,9 +379,9 @@ SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString&            theScrip
   while ( from < end && ( to = theScript.Location( "\n", from, end )))
   {
     if ( to != from )
-        // cut out and store a command
-        aNoteBook->AddCommand( theScript.SubString( from, to - 1 ));
-      from = to + 1;
+      // cut out and store a command
+      aNoteBook->AddCommand( theScript.SubString( from, to - 1 ));
+    from = to + 1;
   }
 
   aNoteBook->ReplaceVariables();
@@ -416,12 +450,14 @@ SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString&            theScrip
 
 _pyGen::_pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod,
                Resource_DataMapOfAsciiStringAsciiString& theObjectNames,
+               std::set< TCollection_AsciiString >&      theRemovedObjIDs,
                SALOMEDS::Study_ptr&                      theStudy,
                const bool                                theToKeepAllCommands)
   : _pyObject( new _pyCommand( "", 0 )),
     myNbCommands( 0 ),
     myID2AccessorMethod( theEntry2AccessorMethod ),
     myObjectNames( theObjectNames ),
+    myRemovedObjIDs( theRemovedObjIDs ),
     myNbFilters( 0 ),
     myToKeepAllCommands( theToKeepAllCommands ),
     myStudy( SALOMEDS::Study::_duplicate( theStudy )),
@@ -462,7 +498,7 @@ _pyGen::_pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod
 
 //================================================================================
 /*!
- * \brief name of SMESH_Gen in smesh.py
+ * \brief name of SMESH_Gen in smeshBuilder.py
  */
 //================================================================================
 
@@ -787,7 +823,7 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
       method == "CreateMeshesFromSAUV"||
       method == "CreateMeshesFromGMF" )
   {
-    for(int ind = 0;ind<theCommand->GetNbResultValues();ind++)
+    for ( int ind = 0; ind < theCommand->GetNbResultValues(); ind++ )
     {
       _pyID meshID = theCommand->GetResultValue(ind+1);
       if ( !theCommand->IsStudyEntry( meshID ) ) continue;
@@ -880,7 +916,7 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
 
   // Replace name of SMESH_Gen
 
-  // names of SMESH_Gen methods fully equal to methods defined in smesh.py
+  // names of SMESH_Gen methods fully equal to methods defined in smeshBuilder.py
   static TStringSet smeshpyMethods;
   if ( smeshpyMethods.empty() ) {
     const char * names[] =
@@ -893,7 +929,7 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
     // smeshgen.Method() --> smesh.Method()
     theCommand->SetObject( SMESH_2smeshpy::SmeshpyName() );
   else
-    // smeshgen.Method() --> smesh.smesh.Method()
+    // smeshgen.Method() --> smesh.Method()
     theCommand->SetObject( SMESH_2smeshpy::GenName() );
 }
 
@@ -946,7 +982,7 @@ void _pyGen::Flush()
   for ( hyp = myHypos.begin(); hyp != myHypos.end(); ++hyp )
     if ( !hyp->IsNull() ) {
       (*hyp)->Flush();
-      // smeshgen.CreateHypothesis() --> smesh.smesh.CreateHypothesis()
+      // smeshgen.CreateHypothesis() --> smesh.CreateHypothesis()
       if ( !(*hyp)->IsWrapped() )
         (*hyp)->GetCreationCmd()->SetObject( SMESH_2smeshpy::GenName() );
     }
@@ -1368,6 +1404,19 @@ bool _pyGen::IsNotPublished(const _pyID& theObjID) const
   return true; // SMESH object not in study
 }
 
+//================================================================================
+/*!
+ * \brief Remove object name from myObjectNames that leads to that SetName() for
+ *        this object is not dumped
+ *  \param [in] theObjID - entry of the object whose creation command was eliminated
+ */
+//================================================================================
+
+void _pyGen::ObjectCreationRemoved(const _pyID& theObjID)
+{
+  myRemovedObjIDs.insert( theObjID );
+}
+
 //================================================================================
 /*!
  * \brief Return reader of  hypotheses of plugins
@@ -1962,7 +2011,7 @@ void _pyMesh::ClearCommands()
 
 void _pyMesh::addFatherMesh( const _pyID& meshID )
 {
-  if ( !meshID.IsEmpty() )
+  if ( !meshID.IsEmpty() && meshID != GetID() )
     addFatherMesh( Handle(_pyMesh)::DownCast( theGen->FindObject( meshID )));
 }
 
@@ -1974,7 +2023,7 @@ void _pyMesh::addFatherMesh( const _pyID& meshID )
 
 void _pyMesh::addFatherMesh( const Handle(_pyMesh)& mesh )
 {
-  if ( !mesh.IsNull() )
+  if ( !mesh.IsNull() && mesh->GetID() != GetID() )
   {
     //myFatherMeshes.push_back( mesh );
     mesh->myChildMeshes.push_back( this );
@@ -3002,18 +3051,23 @@ void _pyNumberOfSegmentsHyp::Flush()
   list<Handle(_pyCommand)>::reverse_iterator cmd = myUnusedCommands.rbegin();
   int distrTypeNb = 0;
   for ( ; !distrTypeNb && cmd != myUnusedCommands.rend(); ++cmd )
-    if ( (*cmd)->GetMethod() == "SetDistrType" )
-      distrTypeNb = (*cmd)->GetOrderNb();
-    else if (IsWrapped() && (*cmd)->GetMethod() == "SetObjectEntry" )
+    if ( (*cmd)->GetMethod() == "SetDistrType" ) {
+      if ( cmd != myUnusedCommands.rbegin() )
+        distrTypeNb = (*cmd)->GetOrderNb();
+    }
+    else if (IsWrapped() && (*cmd)->GetMethod() == "SetObjectEntry" ) {
       (*cmd)->Clear();
-
+    }
   // clear commands before the last SetDistrType()
   list<Handle(_pyCommand)> * cmds[2] = { &myArgCommands, &myUnusedCommands };
+  set< int > treatedCmdNbs; // avoid treating same cmd twice
   for ( int i = 0; i < 2; ++i ) {
     set<TCollection_AsciiString> uniqueMethods;
     list<Handle(_pyCommand)> & cmdList = *cmds[i];
     for ( cmd = cmdList.rbegin(); cmd != cmdList.rend(); ++cmd )
     {
+      if ( !treatedCmdNbs.insert( (*cmd)->GetOrderNb() ).second )
+        continue;// avoid treating same cmd twice
       bool clear = ( (*cmd)->GetOrderNb() < distrTypeNb );
       const TCollection_AsciiString& method = (*cmd)->GetMethod();
       if ( !clear || method == "SetNumberOfSegments" ) {
@@ -3184,22 +3238,21 @@ const TCollection_AsciiString & _pyCommand::GetResultValue()
 //================================================================================
 /*!
  * \brief Return number of python command result value ResultValue = Obj.Meth()
-  * \retval const int
  */
 //================================================================================
 
-const int _pyCommand::GetNbResultValues()
+int _pyCommand::GetNbResultValues()
 {
+  int nb     = 0;
   int begPos = 1;
-  int Nb=0;
   int endPos = myString.Location( "=", 1, Length() );
-  TCollection_AsciiString str = "";
-  while ( begPos < endPos) {
-    str = GetWord( myString, begPos, true );
+  while ( begPos < endPos )
+  {
+    _AString str = GetWord( myString, begPos, true );
     begPos = begPos+ str.Length();
-    Nb++;
+    nb++;
   }
-  return (Nb-1);
+  return (nb-1);
 }
 
 
@@ -3263,7 +3316,7 @@ const TCollection_AsciiString & _pyCommand::GetObject()
     }
     myObj = GetWord( myString, begPos, true );
     // check if object is complex,
-    // so far consider case like "smesh.smesh.Method()"
+    // so far consider case like "smesh.Method()"
     if ( int bracketPos = myString.Location( "(", begPos, Length() )) {
       //if ( bracketPos==0 ) bracketPos = Length();
       int dotPos = begPos+myObj.Length();
@@ -3662,9 +3715,9 @@ void _pyCommand::Comment()
     myString.Insert( i, "#" );
     for ( int iPart = 0; iPart < myBegPos.Length(); ++iPart )
     {
-      int begPos = GetBegPos( iPart );
+      int begPos = GetBegPos( iPart + 1 );
       if ( begPos != UNKNOWN )
-        SetBegPos( iPart, begPos + 1 );
+        SetBegPos( iPart + 1, begPos + 1 );
     }
   }
 }