Salome HOME
Typo fixes by Kunda
[modules/smesh.git] / src / SMESH_I / SMESH_Gen_i.cxx
index c383a29fc6b0e6eb90f2d4c131d174d19652d798..7b403d9aabe014de939e7796469af2285351e8c5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2019  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
@@ -462,9 +462,10 @@ GenericHypothesisCreator_i* SMESH_Gen_i::getHypothesisCreator(const char* theHyp
         // report any error, if occurred
 #ifndef WIN32
         const char* anError = dlerror();
-        throw(SALOME_Exception(anError));
+        throw(SALOME_Exception( anError ));
 #else
-        throw(SALOME_Exception(LOCALIZED( "Can't load server meshers plugin library" )));
+        throw(SALOME_Exception ( SMESH_Comment("Can't load meshers plugin library " )
+                                 << aPlatformLibName));
 #endif
       }
 
@@ -474,7 +475,8 @@ GenericHypothesisCreator_i* SMESH_Gen_i::getHypothesisCreator(const char* theHyp
         (GetHypothesisCreator)GetProc( libHandle, "GetHypothesisCreator" );
       if (!procHandle)
       {
-        throw(SALOME_Exception(LOCALIZED("bad hypothesis plugin library")));
+        throw(SALOME_Exception(SMESH_Comment("bad hypothesis plugin library")
+                               << aPlatformLibName ));
         UnLoadLib(libHandle);
       }
 
@@ -483,7 +485,8 @@ GenericHypothesisCreator_i* SMESH_Gen_i::getHypothesisCreator(const char* theHyp
       aCreator = procHandle(theHypName);
       if (!aCreator)
       {
-        throw(SALOME_Exception(LOCALIZED("no such a hypothesis in this plugin")));
+        throw(SALOME_Exception( SMESH_Comment( theHypName ) << " is missing from "
+                                << aPlatformLibName));
       }
       // map hypothesis creator to a hypothesis name
       myHypCreatorMap[string(theHypName)] = aCreator;
@@ -721,7 +724,7 @@ StudyContext* SMESH_Gen_i::GetStudyContext()
 /*!
  *  SMESH_Gen_i::CreateHypothesis
  *
- *  Create hypothesis/algorothm of given type and publish it in the study
+ *  Create hypothesis/algorithm of given type and publish it in the study
  */
 //=============================================================================
 
@@ -1993,14 +1996,16 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
 void SMESH_Gen_i::CancelCompute( SMESH::SMESH_Mesh_ptr theMesh,
                                  GEOM::GEOM_Object_ptr theShapeObject )
 {
-  SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
-  ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
-  TopoDS_Shape myLocShape;
-  if(theMesh->HasShapeToMesh())
-    myLocShape = GeomObjectToShape( theShapeObject );
-  else
-    myLocShape = SMESH_Mesh::PseudoShape();
-  myGen.CancelCompute( myLocMesh, myLocShape);
+  if ( SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() ))
+  {
+    ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
+    TopoDS_Shape myLocShape;
+    if(theMesh->HasShapeToMesh())
+      myLocShape = GeomObjectToShape( theShapeObject );
+    else
+      myLocShape = SMESH_Mesh::PseudoShape();
+    myGen.CancelCompute( myLocMesh, myLocShape);
+  }
 }
 
 //=============================================================================
@@ -2431,14 +2436,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 +2461,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 +2486,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();
@@ -2497,6 +2512,22 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray,
   TGroupsMap       groupsMap;
   TListOfNewGroups listOfNewGroups;
 
+  if ( !CORBA::is_nil( theMeshToAppendTo ))
+  {
+    // fill groupsMap with existing groups
+    SMESH::ListOfGroups_var groups = theMeshToAppendTo->GetGroups();
+    for ( CORBA::ULong i = 0; i < groups->length(); ++i )
+    {
+      SMESH::SMESH_Group_var group = SMESH::SMESH_Group::_narrow( groups[ i ]);
+      if ( !group->_is_nil() )
+      {
+        CORBA::String_var  name = group->GetName();
+        SMESH::ElementType type = group->GetType();
+        groupsMap[ TNameAndType( name.in(), type ) ].push_back( group );
+      }
+    }
+  }
+
   ::SMESH_MeshEditor               newEditor( &locMesh );
   ::SMESH_MeshEditor::ElemFeatures elemType;
 
@@ -2507,6 +2538,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 +2726,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 +2986,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 +3004,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()
 
@@ -3071,6 +3109,11 @@ namespace // utils for CopyMeshWithGeom()
         {
           findNewIDs( oldIndices[i], newIndices );
         }
+        if ( newIndices.size() < oldIndices->length() ) // issue #17096
+        {
+          newIndices.clear();
+          newShape = getInPlace( oldShape );
+        }
         if ( !newIndices.empty() )
         {
           try
@@ -3159,7 +3202,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;
     }
@@ -3242,6 +3297,27 @@ namespace // utils for CopyMeshWithGeom()
       }
     }
 
+    //================================================================================
+    /*!
+     * \brief Get new sub-shape by calling GetInPlace()
+     */
+    GEOM::GEOM_Object_ptr getInPlace( GEOM::GEOM_Object_ptr oldShape )
+    {
+      GEOM::GEOM_Object_var newShape;
+
+      GEOM::GEOM_Object_var   mainShapeNew = myNewMesh_i->GetShapeToMesh();
+      GEOM::GEOM_Gen_var           geomGen = myGen_i->GetGeomEngine();
+      GEOM::GEOM_IShapesOperations_wrap op = geomGen->GetIShapesOperations();
+      try
+      {
+        newShape = op->GetInPlace( mainShapeNew, oldShape );
+      }
+      catch( ... )
+      {
+      }
+      return newShape._retn();
+    }
+
     //================================================================================
     /*!
      * \brief Find a new sub-shape indices by an old one in myGIPMap. Return
@@ -3388,7 +3464,7 @@ namespace // utils for CopyMeshWithGeom()
       seq[ seq->length() - 1 ] = item;
     }
   }
-}
+} // namespace // utils for CopyMeshWithGeom()
 
 //================================================================================
 /*!
@@ -3406,7 +3482,7 @@ namespace // utils for CopyMeshWithGeom()
  *  \param [out] invalidEntries - return study entries of objects whose
  *         counterparts are not found in the newGeometry, followed by entries
  *         of mesh sub-objects that are invalid because they depend on a not found
- *         preceeding sub-shape
+ *         preceding sub-shape
  *  \return CORBA::Boolean - is a success
  */
 //================================================================================
@@ -3450,6 +3526,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 +3640,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 +3699,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 +3711,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 +3725,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 +3853,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 +3866,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 );
 
@@ -3951,6 +4042,9 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
   cmd+="\" \"";
   cmd+=meshfile;
   cmd+="\"";
+#ifdef WIN32
+  cmd+=" 2>NUL";
+#endif
   system(cmd.ToCString());
 
   // MED writer to be used by storage process
@@ -3980,7 +4074,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 );
               }
@@ -5153,6 +5247,10 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
             try { // protect persistence mechanism against exceptions
               myHyp = this->createHypothesis( hypname.c_str(), libname.c_str() );
             }
+            catch( SALOME::SALOME_Exception& ex )
+            {
+              INFOS( "Exception during hypothesis creation: " << ex.details.text );
+            }
             catch (...) {
               INFOS( "Exception during hypothesis creation" );
             }
@@ -5303,7 +5401,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 +5413,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 +5679,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 +5742,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 +5791,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 );
       }
@@ -6047,7 +6145,8 @@ CORBA::Boolean SMESH_Gen_i::IsApplicable ( const char*           theAlgoType,
   if (aCreator)
   {
     TopoDS_Shape shape = GeomObjectToShape( theGeomObject );
-    return shape.IsNull() || aCreator->IsApplicable( shape, toCheckAll );
+    const SMESH_Algo::Features& feat = SMESH_Algo::GetFeatures( theAlgoType );
+    return shape.IsNull() || aCreator->IsApplicable( shape, toCheckAll, feat._dim );
   }
   else
   {