Salome HOME
23627: [IMACS] ASERIS: project point to the mesh and create a slot
[modules/smesh.git] / src / SMESH_I / SMESH_Gen_i.cxx
index c383a29fc6b0e6eb90f2d4c131d174d19652d798..2e902f5320f9ca3e3e46e22f1c1f769890ffa54e 100644 (file)
@@ -2431,14 +2431,16 @@ SMESH::SMESH_Mesh_ptr
 SMESH_Gen_i::Concatenate(const SMESH::ListOfIDSources& theMeshesArray,
                          CORBA::Boolean                theUniteIdenticalGroups,
                          CORBA::Boolean                theMergeNodesAndElements,
-                         CORBA::Double                 theMergeTolerance)
+                         CORBA::Double                 theMergeTolerance,
+                         SMESH::SMESH_Mesh_ptr         theMeshToAppendTo)
   throw ( SALOME::SALOME_Exception )
 {
   return ConcatenateCommon(theMeshesArray,
                            theUniteIdenticalGroups,
                            theMergeNodesAndElements,
                            theMergeTolerance,
-                           false);
+                           false,
+                           theMeshToAppendTo);
 }
 
 //================================================================================
@@ -2454,14 +2456,16 @@ SMESH::SMESH_Mesh_ptr
 SMESH_Gen_i::ConcatenateWithGroups(const SMESH::ListOfIDSources& theMeshesArray,
                                    CORBA::Boolean                theUniteIdenticalGroups,
                                    CORBA::Boolean                theMergeNodesAndElements,
-                                   CORBA::Double                 theMergeTolerance)
+                                   CORBA::Double                 theMergeTolerance,
+                                   SMESH::SMESH_Mesh_ptr         theMeshToAppendTo)
   throw ( SALOME::SALOME_Exception )
 {
   return ConcatenateCommon(theMeshesArray,
                            theUniteIdenticalGroups,
                            theMergeNodesAndElements,
                            theMergeTolerance,
-                           true);
+                           true,
+                           theMeshToAppendTo);
 }
 
 //================================================================================
@@ -2477,16 +2481,22 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray,
                                CORBA::Boolean                theUniteIdenticalGroups,
                                CORBA::Boolean                theMergeNodesAndElements,
                                CORBA::Double                 theMergeTolerance,
-                               CORBA::Boolean                theCommonGroups)
+                               CORBA::Boolean                theCommonGroups,
+                               SMESH::SMESH_Mesh_ptr         theMeshToAppendTo)
   throw ( SALOME::SALOME_Exception )
 {
   std::unique_ptr< TPythonDump > pPythonDump( new TPythonDump );
   TPythonDump& pythonDump = *pPythonDump; // prevent dump of called methods
 
-  // create mesh
-  SMESH::SMESH_Mesh_var newMesh = CreateEmptyMesh();
-  SMESH_Mesh_i*         newImpl = SMESH::DownCast<SMESH_Mesh_i*>( newMesh );
+  // create mesh if theMeshToAppendTo not provided
+  SMESH::SMESH_Mesh_var newMesh;
+  if ( CORBA::is_nil( theMeshToAppendTo ))
+    newMesh = CreateEmptyMesh();
+  else
+    newMesh = SMESH::SMESH_Mesh::_duplicate( theMeshToAppendTo );
+  SMESH_Mesh_i* newImpl = SMESH::DownCast<SMESH_Mesh_i*>( newMesh );
   if ( !newImpl ) return newMesh._retn();
+  newImpl->Load();
 
   ::SMESH_Mesh&   locMesh = newImpl->GetImpl();
   SMESHDS_Mesh* newMeshDS = locMesh.GetMeshDS();
@@ -2507,6 +2517,8 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray,
     SMESH::SMESH_Mesh_var initMesh = theMeshesArray[i]->GetMesh();
     SMESH_Mesh_i*         initImpl = SMESH::DownCast<SMESH_Mesh_i*>( initMesh );
     if ( !initImpl ) continue;
+    if ( initMesh->_is_equivalent( theMeshToAppendTo ))
+      continue;
     initImpl->Load();
 
     // assure that IDs increments by one during iteration
@@ -2693,11 +2705,12 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray,
 
   // Update Python script
   pythonDump << newMesh << " = " << this
-             << "." << ( theCommonGroups ? "ConcatenateWithGroups" : "Concatenate" ) << "("
+             << "." << ( theCommonGroups ? "ConcatenateWithGroups" : "Concatenate" ) << "( "
              << theMeshesArray << ", "
              << theUniteIdenticalGroups << ", "
              << theMergeNodesAndElements << ", "
-             << TVar( theMergeTolerance ) << ")";
+             << TVar( theMergeTolerance ) << ", "
+             << theMeshToAppendTo << " )";
 
   pPythonDump.reset(); // enable python dump from GetGroups()
 
@@ -2952,6 +2965,7 @@ namespace // utils for CopyMeshWithGeom()
 {
   typedef std::map< std::string, std::string >             TStr2StrMap;
   typedef std::map< std::string, std::set< std::string > > TStr2StrSetMap;
+  //typedef std::map< std::set<int>, int >                   TIdSet2IndexMap;
 
   //================================================================================
   /*!
@@ -2969,6 +2983,9 @@ namespace // utils for CopyMeshWithGeom()
 
     TStr2StrMap   myOld2NewEntryMap; // map of study entries
 
+    //GEOM::ListOfGO_var         mySubshapes; // sub-shapes existing in the new geometry
+    //TIdSet2IndexMap            myIds2SubshapeIndex; // to find an existing sub-shape
+
     bool                       myGIPMapDone;
     GEOM::ListOfListOfLong_var myGIPMap; // filled by GetInPlaceMap()
 
@@ -3159,7 +3176,19 @@ namespace // utils for CopyMeshWithGeom()
       if ( 0 < oldID && oldID < (int)myGIPMap->length() )
       {
         if ( myGIPMap[ oldID ].length() == 1 )
+        {
           newID = myGIPMap[ oldID ][ 0 ];
+        }
+        else if ( myGIPMap[ oldID ].length() > 1 &&
+                  getShapeType( mySrcMesh_i, oldID ) == TopAbs_VERTEX )
+        {
+          // select a meshed VERTEX
+          SMESH_subMesh* newSM;
+          for ( CORBA::ULong i = 0; i < myGIPMap[ oldID ].length() && !newID; ++i )
+            if (( newSM = myNewMesh_i->GetImpl().GetSubMeshContaining( myGIPMap[ oldID ][ i ] )) &&
+                ( !newSM->IsEmpty() ))
+              newID = myGIPMap[ oldID ][ i ];
+        }
       }
       return newID;
     }
@@ -3388,7 +3417,7 @@ namespace // utils for CopyMeshWithGeom()
       seq[ seq->length() - 1 ] = item;
     }
   }
-}
+} // namespace // utils for CopyMeshWithGeom()
 
 //================================================================================
 /*!
@@ -3450,6 +3479,7 @@ throw ( SALOME::SALOME_Exception )
 
   SMESH_Mesh_i* srcMesh_i = SMESH::DownCast<SMESH_Mesh_i*>( theSourceMesh );
   SMESH_Mesh_i* newMesh_i = SMESH::DownCast<SMESH_Mesh_i*>( theNewMesh );
+  srcMesh_i->Load();
 
   ShapeMapper shapeMapper( srcMesh_i, newMesh_i, this );
 
@@ -3563,9 +3593,9 @@ throw ( SALOME::SALOME_Exception )
 
 
   // copy mesh elements, keeping IDs
+  SMESHDS_Mesh* newMeshDS = newMesh_i->GetImpl().GetMeshDS();
   if ( theToCopyElements && theSourceMesh->NbNodes() > 0 )
   {
-    SMESHDS_Mesh* newMeshDS = newMesh_i->GetImpl().GetMeshDS();
     ::SMESH_MeshEditor editor( &newMesh_i->GetImpl() );
     ::SMESH_MeshEditor::ElemFeatures elemData;
 
@@ -3622,6 +3652,8 @@ throw ( SALOME::SALOME_Exception )
       if ( SMESH_subMesh* newSM = newMesh_i->GetImpl().GetSubMeshContaining( newID ))
         newSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
     }
+
+    newMeshDS->Modified();
   }
 
 
@@ -3632,7 +3664,7 @@ throw ( SALOME::SALOME_Exception )
   SALOME::GenericObj_wrap< SMESH::FilterManager > filterMgr = CreateFilterManager();
 
   SMESH::ListOfGroups_var groups = theSourceMesh->GetGroups();
-  CORBA::ULong nbGroups = groups->length(), nbAddedGroups = 0;
+  CORBA::ULong nbGroups = theToCopyGroups ? groups->length() : 0, nbAddedGroups = 0;
   for ( CORBA::ULong i = 0; i < nbGroups + nbAddedGroups; ++i )
   {
     SMESH::SMESH_Group_var         stdlGroup = SMESH::SMESH_Group::_narrow        ( groups[ i ]);
@@ -3646,12 +3678,20 @@ throw ( SALOME::SALOME_Exception )
 
     if ( !stdlGroup->_is_nil() )
     {
-      if ( theToCopyElements )
+      if ( newMeshDS->GetMeshInfo().NbElements( SMDSAbs_ElementType( elemType )) > 0 )
       {
         SMESH::long_array_var elemIDs = stdlGroup->GetIDs();
-        stdlGroup = theNewMesh->CreateGroup( elemType, name );
-        stdlGroup->Add( elemIDs );
-        newGroup = SMESH::SMESH_GroupBase::_narrow( stdlGroup );
+        const bool isElem = ( elemType != SMESH::NODE );
+        CORBA::ULong iE = 0;
+        for ( ; iE < elemIDs->length(); ++iE ) // check if any element has been copied
+          if ( newMeshDS->GetElementType( elemIDs[ iE ], isElem ) != SMDSAbs_All )
+            break;
+        if ( iE < elemIDs->length() )
+        {
+          stdlGroup = theNewMesh->CreateGroup( elemType, name );
+          stdlGroup->Add( elemIDs );
+          newGroup = SMESH::SMESH_GroupBase::_narrow( stdlGroup );
+        }
       }
     }
     else if ( !geomGroup->_is_nil() )
@@ -3766,7 +3806,7 @@ throw ( SALOME::SALOME_Exception )
     SALOMEDS::SObject_wrap newSO = ObjectToSObject( newGroup );
     if ( !srcSO->_is_nil() )
     {
-      CORBA::String_var srcID, newID;
+      CORBA::String_var srcID, newID("");
       srcID = srcSO->GetID();
       if ( !newSO->_is_nil() )
         newID = newSO->GetID();
@@ -3779,12 +3819,16 @@ throw ( SALOME::SALOME_Exception )
 
   } // loop on groups
 
-  // set mesh name
-  SALOMEDS::SObject_wrap soNew = ObjectToSObject( theNewMesh );
-  SALOMEDS::SObject_wrap soOld = ObjectToSObject( theSourceMesh );
-  CORBA::String_var oldName = soOld->GetName();
-  SetName( soNew, oldName.in(), "Mesh" );
+  newMeshDS->CompactMesh();
 
+  // set mesh name
+  if ( !theMeshName || !theMeshName[0] )
+  {
+    SALOMEDS::SObject_wrap soNew = ObjectToSObject( theNewMesh );
+    SALOMEDS::SObject_wrap soOld = ObjectToSObject( theSourceMesh );
+    CORBA::String_var oldName = soOld->GetName();
+    SetName( soNew, oldName.in(), "Mesh" );
+  }
   // mark invalid objects
   shapeMapper.GetInvalid( theInvalidEntries, invalidSObjects );
 
@@ -3980,7 +4024,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                 CORBA::String_var objStr = GetORB()->object_to_string( grImpl->_this() );
                 int anId = myStudyContext->findId( string( objStr.in() ) );
                 char grpName[ 30 ];
-                sprintf( grpName, "Group %d", anId );
+                sprintf( grpName, "Group %d %d", anId, grImpl->GetLocalID() );
                 SMESHDS_GroupBase* aGrpBaseDS = grImpl->GetGroupDS();
                 aGrpBaseDS->SetStoreName( grpName );
               }
@@ -5303,7 +5347,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
       // get mesh old id
       CORBA::String_var iorString = GetORB()->object_to_string( myNewMeshImpl->_this() );
       int newId = myStudyContext->findId( iorString.in() );
-      int id = myStudyContext->getOldId( newId );
+      int meshOldId = myStudyContext->getOldId( newId );
 
       // try to find mesh data dataset
       if ( aTopGroup->ExistInternalObject( "Has data" ) ) {
@@ -5315,10 +5359,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
         aDataset->ReadFromDisk( strHasData );
         aDataset->CloseOnDisk();
         if ( strcmp( strHasData, "1") == 0 ) {
-          // read mesh data from MED file
-          // myReader.SetMesh( mySMESHDSMesh );
-          // myReader.SetMeshId( id );
-          // myReader.Perform();
           hasData = true;
         }
         delete [] strHasData;
@@ -5585,9 +5625,13 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
             // check if it is a group
             if ( name_dataset.substr( 0, 5 ) == "Group" ) {
               // --> get group id
-              int subid = atoi( name_dataset.substr( 5 ).c_str() );
+              char * endptr;
+              int subid = strtol( name_dataset.data() + 5, &endptr, 10 );
               if ( subid <= 0 )
                 continue;
+              int groupID = -1; // group local ID (also persistent)
+              if ( *endptr )
+                groupID = atoi( endptr + 1 );
               aDataset = new HDFdataset( name_dataset.c_str(), aGroup );
               aDataset->OpenOnDisk();
 
@@ -5644,7 +5688,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
               // Create group servant
               SMESH::ElementType type = (SMESH::ElementType)(ii - GetNodeGroupsTag() + 1);
               SMESH::SMESH_GroupBase_var aNewGroup = SMESH::SMESH_GroupBase::_duplicate
-                ( myNewMeshImpl->createGroup( type, nameFromFile, aShape, predicate ) );
+                ( myNewMeshImpl->createGroup( type, nameFromFile, groupID, aShape, predicate ) );
               delete [] nameFromFile;
               // Obtain a SMESHDS_Group object
               if ( aNewGroup->_is_nil() )
@@ -5693,10 +5737,10 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
       } // reading GROUPs
 
       // instead of reading mesh data, we read only brief information of all
-      // objects: mesh, groups, sub-meshes (issue 0021208 )
+      // objects: mesh, groups, sub-meshes (issue 0021208)
       if ( hasData )
       {
-        SMESH_PreMeshInfo::LoadFromFile( myNewMeshImpl, id,
+        SMESH_PreMeshInfo::LoadFromFile( myNewMeshImpl, meshOldId,
                                          meshfile.ToCString(), filename.ToCString(),
                                          !isMultiFile );
       }