Salome HOME
Merge from V6_main 13/12/2012
[modules/smesh.git] / src / SMESH_I / SMESH_2smeshpy.cxx
index 91f6e7effd1d6482db1de829fd9aaa67fac89d1d..4dc84a2a15083b369efa9098fc46631bdc267555 100644 (file)
@@ -124,6 +124,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
@@ -533,10 +558,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 +576,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 +760,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 +818,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" ||
@@ -1503,6 +1535,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 +1569,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();
@@ -1541,26 +1600,42 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
   {
     _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 ) &&
-           geomID == (*cmd)->GetArg( 1 )) { // 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();
@@ -1588,23 +1663,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
   {
@@ -1742,6 +1800,7 @@ void _pyMesh::Flush()
       addCmd->SetArg( 1, algoID );
       if ( isLocalAlgo )
         addCmd->SetArg( 2, geom );
+      myNotConvertedAddHypCmds.push_back( addCmd );
     }
   }
 
@@ -1762,6 +1821,7 @@ void _pyMesh::Flush()
       addCmd->SetArg( 1, hypID );
       if ( geom != GetGeom() )
         addCmd->SetArg( 2, geom );
+      myNotConvertedAddHypCmds.push_back( addCmd );
     }
   }
 
@@ -1911,14 +1971,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",
@@ -1937,7 +1998,21 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
     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() ) {
@@ -1949,13 +2024,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)
     {
@@ -1980,7 +2063,7 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
     }
   }
 
-  // ExtrusionSweep0D() -> ExtrusionSweep()
+  // ExtrusionSweep0D()       -> ExtrusionSweep()
   // ExtrusionSweepObject0D() -> ExtrusionSweepObject()
   if ( !isPyMeshMethod && ( method == "ExtrusionSweep0D"  ||
                             method == "ExtrusionSweepObject0D" ))
@@ -1990,19 +2073,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" ||
@@ -2027,14 +2098,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" )
@@ -2065,10 +2128,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 );
@@ -2076,7 +2144,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();
@@ -3748,7 +3816,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 );
   }
@@ -3846,6 +3914,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
@@ -3923,8 +4006,6 @@ void _pyGroup::Process( const Handle(_pyCommand)& theCommand)
 //================================================================================
 /*!
  * \brief Prevent clearing "DoubleNode...() command if a group created by it is removed
- * 
- * 
  */
 //================================================================================