]> SALOME platform Git repositories - modules/smesh.git/blobdiff - src/SMESH_I/SMESH_2smeshpy.cxx
Salome HOME
0022108: EDF 2547 SMESH: Duplicate elements only
[modules/smesh.git] / src / SMESH_I / SMESH_2smeshpy.cxx
index cabe36237be79be987973860dd77cfec785cfa0b..7ff09306b48e375b64eb1f49dd9625c0637e0cc2 100644 (file)
@@ -285,6 +285,8 @@ namespace {
     //   - FT_BallDiameter          = 37
     // v 6.7.1: FT_Undefined == 45, new items:
     //   - FT_EntityType            = 36
+    // v 7.3.0: FT_Undefined == 46, new items:
+    //   - FT_ConnectedElements     = 39
     //
     // It's necessary to continue recording this history and to fill
     // undef2newItems (see below) accordingly.
@@ -302,10 +304,9 @@ namespace {
         undef2newItems[ 39 ].assign( items, items+6 ); }
       { int items[] = { 14, 15, 16, 17 };
         undef2newItems[ 43 ].assign( items, items+4 ); }
-      { int items[] = { 37 };
-        undef2newItems[ 44 ].assign( items, items+1 ); }
-      { int items[] = { 36 };
-        undef2newItems[ 45 ].assign( items, items+1 ); }
+      undef2newItems[ 44 ].push_back( 37 );
+      undef2newItems[ 45 ].push_back( 36 );
+      undef2newItems[ 46 ].push_back( 39 );
     }
 
     int iType     = Type.IntegerValue();
@@ -700,7 +701,7 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
     // 1    2       3         4            5           6       7        8         9             10
     // in order to avoid the problem of type mismatch of long and FunctorType
     const TCollection_AsciiString
-      SMESH("SMESH."), dfltFunctor("SMESH.FT_Undefined"), dftlTol("1e-07"), dftlPreci("-1");
+      SMESH("SMESH."), dfltFunctor("SMESH.FT_Undefined"), dfltTol("1e-07"), dfltPreci("-1");
     TCollection_AsciiString
       Type          = aCommand->GetArg(1),  // long
       Compare       = aCommand->GetArg(2),  // long
@@ -744,7 +745,7 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
         // set SMESH.EntityType instead of a numerical Threshold
         const char* types[SMESH::Entity_Ball+1] = {
           "Entity_Node", "Entity_0D", "Entity_Edge", "Entity_Quad_Edge",
-          "Entity_Triangle", "Entity_Quad_Triangle",
+          "Entity_Triangle", "Entity_Quad_Triangle", "Entity_BiQuad_Triangle",
           "Entity_Quadrangle", "Entity_Quad_Quadrangle", "Entity_BiQuad_Quadrangle",
           "Entity_Polygon", "Entity_Quad_Polygon", "Entity_Tetra", "Entity_Quad_Tetra",
           "Entity_Pyramid", "Entity_Quad_Pyramid",
@@ -755,7 +756,7 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
           Threshold = SMESH + types[ iGeom ];
       }
     }
-    if ( ThresholdID.Length() != 2 && ThresholdStr.Length() != 2) // not '' or ""
+    if ( ThresholdID.Length() != 2 ) // neither '' nor ""
       aCommand->SetArg( 4, ThresholdID.SubString( 2, ThresholdID.Length()-1 )); // shape entry
     else if ( ThresholdStr.Length() != 2 )
       aCommand->SetArg( 4, ThresholdStr );
@@ -765,7 +766,7 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
       aCommand->SetArg( 4, Threshold );
     // find the last not default arg
     int lastDefault = 8;
-    if ( Tolerance == dftlTol ) {
+    if ( Tolerance == dfltTol ) {
       lastDefault = 7;
       if ( BinaryOp == dfltFunctor ) {
         lastDefault = 6;
@@ -776,7 +777,7 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
     if ( 5 < lastDefault ) aCommand->SetArg( 5, UnaryOp );
     if ( 6 < lastDefault ) aCommand->SetArg( 6, BinaryOp );
     if ( 7 < lastDefault ) aCommand->SetArg( 7, Tolerance );
-    if ( Precision != dftlPreci )
+    if ( Precision != dfltPreci )
     {
       TCollection_AsciiString crit = aCommand->GetResultValue();
       aCommand->GetString() += "; ";
@@ -812,8 +813,7 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
   }
   if ( method == "CreateMeshesFromUNV" ||
        method == "CreateMeshesFromSTL" ||
-       method == "CreateMeshesFromCGNS" ||
-       method == "CopyMesh" )
+       method == "CopyMesh" ) // command result is a mesh
   {
     Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue() );
     myMeshes.insert( make_pair( mesh->GetID(), mesh ));
@@ -821,7 +821,8 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
   }
   if( method == "CreateMeshesFromMED" ||
       method == "CreateMeshesFromSAUV"||
-      method == "CreateMeshesFromGMF" )
+      method == "CreateMeshesFromCGNS" ||
+      method == "CreateMeshesFromGMF" ) // command result is ( [mesh1,mesh2], status )
   {
     for ( int ind = 0; ind < theCommand->GetNbResultValues(); ind++ )
     {
@@ -1406,7 +1407,7 @@ bool _pyGen::IsNotPublished(const _pyID& theObjID) const
 
 //================================================================================
 /*!
- * \brief Remove object name from myObjectNames that leads to that SetName() for
+ * \brief Add an object to myRemovedObjIDs that leads to that SetName() for
  *        this object is not dumped
  *  \param [in] theObjID - entry of the object whose creation command was eliminated
  */
@@ -1615,31 +1616,61 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
     myGroups.push_back( group );
     theGen->AddObject( group );
   }
+  // ----------------------------------------------------------------------
   // update list of groups
   else if ( method == "GetGroups" )
   {
+    bool allGroupsRemoved = true;
     TCollection_AsciiString grIDs = theCommand->GetResultValue();
-    list< _pyID > idList = theCommand->GetStudyEntries( grIDs );
-    list< _pyID >::iterator grID = idList.begin();
+    list< _pyID >          idList = theCommand->GetStudyEntries( grIDs );
+    list< _pyID >::iterator  grID = idList.begin();
+    const int nbGroupsBefore = myGroups.size();
+    Handle(_pyObject) obj;
     for ( ; grID != idList.end(); ++grID )
     {
-      Handle(_pyObject) obj = theGen->FindObject( *grID );
+      obj = theGen->FindObject( *grID );
       if ( obj.IsNull() )
       {
         Handle(_pyGroup) group = new _pyGroup( theCommand, *grID );
         theGen->AddObject( group );
         myGroups.push_back( group );
+        obj = group;
       }
+      if ( !obj->CanClear() )
+        allGroupsRemoved = false;
+    }
+    if ( nbGroupsBefore == myGroups.size() ) // no new _pyGroup created
+      obj->AddProcessedCmd( theCommand ); // to clear theCommand if all groups are removed
+
+    if ( !allGroupsRemoved && !theGen->IsToKeepAllCommands() )
+    {
+      // check if the preceding command is Compute();
+      // if GetGroups() is just after Compute(), this can mean that the groups
+      // were created by some algorithm and hence Compute() should not be discarded
+      std::list< Handle(_pyCommand) >& cmdList = theGen->GetCommands();
+      std::list< Handle(_pyCommand) >::iterator cmd = cmdList.begin();
+      while ( (*cmd)->GetMethod() == "GetGroups" )
+        ++cmd;
+      if ( myLastComputeCmd == (*cmd))
+        // protect last Compute() from clearing by the next Compute()
+        myLastComputeCmd.Nullify();
     }
   }
+  // ----------------------------------------------------------------------
   // notify a group about full removal
-  else if ( method == "RemoveGroupWithContents" )
+  else if ( method == "RemoveGroupWithContents" ||
+            method == "RemoveGroup")
   {
     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();
+      {
+        if ( method == "RemoveGroupWithContents" )
+          grp->RemovedWithContents();
+        // to clear RemoveGroup() if the group creation is cleared
+        grp->AddProcessedCmd( theCommand );
+      }
     }
   }
   // ----------------------------------------------------------------------
@@ -2011,7 +2042,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 )));
 }
 
@@ -2023,7 +2054,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 );
@@ -2067,7 +2098,7 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
       "RemoveElements","RemoveNodes","RemoveOrphanNodes","AddNode","Add0DElement","AddEdge","AddFace","AddPolygonalFace","AddBall",
       "AddVolume","AddPolyhedralVolume","AddPolyhedralVolumeByFaces","MoveNode", "MoveClosestNodeToPoint",
       "InverseDiag","DeleteDiag","Reorient","ReorientObject",
-      "TriToQuad","TriToQuadObject", "SplitQuad","SplitQuadObject",
+      "TriToQuad","TriToQuadObject", "QuadTo4Tri", "SplitQuad","SplitQuadObject",
       "BestSplit","Smooth","SmoothObject","SmoothParametric","SmoothParametricObject",
       "ConvertToQuadratic","ConvertFromQuadratic","RenumberNodes","RenumberElements",
       "RotationSweep","RotationSweepObject","RotationSweepObject1D","RotationSweepObject2D",
@@ -2079,8 +2110,8 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
       "MergeElements","MergeEqualElements","SewFreeBorders","SewConformFreeBorders",
       "SewBorderToSide","SewSideElements","ChangeElemNodes","GetLastCreatedNodes",
       "GetLastCreatedElems",
-      "MirrorMakeMesh","MirrorObjectMakeMesh","TranslateMakeMesh",
-      "TranslateObjectMakeMesh","RotateMakeMesh","RotateObjectMakeMesh","MakeBoundaryMesh",
+      "MirrorMakeMesh","MirrorObjectMakeMesh","TranslateMakeMesh","TranslateObjectMakeMesh",
+      "Scale","ScaleMakeMesh","RotateMakeMesh","RotateObjectMakeMesh","MakeBoundaryMesh",
       "MakeBoundaryElements", "SplitVolumesIntoTetra"
       ,"" }; // <- mark of the end
     sameMethods.Insert( names );
@@ -2106,7 +2137,7 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
   if (diffLastTwoArgsMethods.empty() ) {
     const char * names[] = {
       "MirrorMakeGroups","MirrorObjectMakeGroups",
-      "TranslateMakeGroups","TranslateObjectMakeGroups",
+      "TranslateMakeGroups","TranslateObjectMakeGroups","ScaleMakeGroups",
       "RotateMakeGroups","RotateObjectMakeGroups",
       ""};// <- mark of the end
     diffLastTwoArgsMethods.Insert( names );
@@ -3315,19 +3346,22 @@ const TCollection_AsciiString & _pyCommand::GetObject()
         begPos = 1;
     }
     myObj = GetWord( myString, begPos, true );
-    // check if object is complex,
-    // so far consider case like "smesh.Method()"
-    if ( int bracketPos = myString.Location( "(", begPos, Length() )) {
-      //if ( bracketPos==0 ) bracketPos = Length();
-      int dotPos = begPos+myObj.Length();
-      while ( dotPos+1 < bracketPos ) {
-        if ( int pos = myString.Location( ".", dotPos+1, bracketPos ))
-          dotPos = pos;
-        else
-          break;
+    if ( begPos != EMPTY )
+    {
+      // check if object is complex,
+      // so far consider case like "smesh.Method()"
+      if ( int bracketPos = myString.Location( "(", begPos, Length() )) {
+        //if ( bracketPos==0 ) bracketPos = Length();
+        int dotPos = begPos+myObj.Length();
+        while ( dotPos+1 < bracketPos ) {
+          if ( int pos = myString.Location( ".", dotPos+1, bracketPos ))
+            dotPos = pos;
+          else
+            break;
+        }
+        if ( dotPos > begPos+myObj.Length() )
+          myObj = myString.SubString( begPos, dotPos-1 );
       }
-      if ( dotPos > begPos+myObj.Length() )
-        myObj = myString.SubString( begPos, dotPos-1 );
     }
     // 1st word after '=' is an object
     // else // no method -> no object
@@ -3715,9 +3749,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 );
     }
   }
 }
@@ -3863,7 +3897,16 @@ _pyID _pyObject::FatherID(const _pyID & childID)
 
 void _pySelfEraser::Flush()
 {
-  if ( GetNbCalls() == 0 )
+  int nbCalls = GetNbCalls();
+  if ( nbCalls > 0 )
+  {
+    // ignore cleared commands
+    std::list< Handle(_pyCommand) >& cmds = GetProcessedCmds();
+    std::list< Handle(_pyCommand) >::const_iterator cmd = cmds.begin();
+    for ( ; cmd != cmds.end(); ++cmd )
+      nbCalls -= (*cmd)->IsEmpty();
+  }
+  if ( nbCalls < 1 )
     GetCreationCmd()->Clear();
 }
 
@@ -4005,6 +4048,10 @@ _pyGroup::_pyGroup(const Handle(_pyCommand)& theCreationCmd, const _pyID & id)
     }
     myFilter = filter;
   }
+  else if ( method == "GetGroups" )
+  {
+    myCanClearCreationCmd = ( theCreationCmd->GetNbResultValues() == 1 );
+  }
   else
   {
     // theCreationCmd does something else apart from creation of this group
@@ -4013,6 +4060,45 @@ _pyGroup::_pyGroup(const Handle(_pyCommand)& theCreationCmd, const _pyID & id)
   }
 }
 
+//================================================================================
+/*!
+ * \brief Check if "[ group1, group2 ] = mesh.GetGroups()" creation command 
+ *        can be cleared
+ */
+//================================================================================
+
+bool _pyGroup::CanClear()
+{
+  if ( IsInStudy() )
+    return false;
+
+  if ( !myCanClearCreationCmd && myCreationCmd->GetMethod() == "GetGroups" )
+  {
+    TCollection_AsciiString grIDs = myCreationCmd->GetResultValue();
+    list< _pyID >          idList = myCreationCmd->GetStudyEntries( grIDs );
+    list< _pyID >::iterator  grID = idList.begin();
+    if ( GetID() == *grID )
+    {
+      myCanClearCreationCmd = true;
+      list< Handle(_pyGroup ) > groups;
+      for ( ; grID != idList.end(); ++grID )
+      {
+        Handle(_pyGroup) group = Handle(_pyGroup)::DownCast( theGen->FindObject( *grID ));
+        if ( group.IsNull() ) continue;
+        groups.push_back( group );
+        if ( group->IsInStudy() )
+          myCanClearCreationCmd = false;
+      }
+      // set myCanClearCreationCmd == true to all groups
+      list< Handle(_pyGroup ) >::iterator group = groups.begin();
+      for ( ; group != groups.end(); ++group )
+        (*group)->myCanClearCreationCmd = myCanClearCreationCmd;
+    }
+  }
+
+  return myCanClearCreationCmd;
+}
+
 //================================================================================
 /*!
  * \brief set myCanClearCreationCmd = true if the main action of the creation