Salome HOME
23514: EDF 16031 - SMESH freezes
[modules/smesh.git] / src / SMESH_I / SMESH_Gen_i.cxx
index 204466afefea833d8bb90b3bfd220ad675a54b84..65d22dab71e0059b4159139526f9e7a1531048f9 100644 (file)
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
 
+#include <BRepPrimAPI_MakeBox.hxx>
+#include <BRepPrimAPI_MakeCylinder.hxx>
+#include <BRepPrimAPI_MakeSphere.hxx>
+#include <BRep_Tool.hxx>
+#include <OSD.hxx>
+#include <TColStd_MapOfAsciiString.hxx>
+#include <TCollection_AsciiString.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
 #include <TopoDS.hxx>
-#include <TopoDS_Iterator.hxx>
-#include <TopoDS_Compound.hxx>
 #include <TopoDS_CompSolid.hxx>
-#include <TopoDS_Solid.hxx>
-#include <TopoDS_Shell.hxx>
-#include <TopoDS_Face.hxx>
-#include <TopoDS_Wire.hxx>
+#include <TopoDS_Compound.hxx>
 #include <TopoDS_Edge.hxx>
-#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Iterator.hxx>
 #include <TopoDS_Shape.hxx>
-#include <TopTools_MapOfShape.hxx>
-#include <TopTools_IndexedMapOfShape.hxx>
-#include <TopTools_ListOfShape.hxx>
-#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopoDS_Shell.hxx>
+#include <TopoDS_Solid.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Wire.hxx>
 #include <gp_Pnt.hxx>
-#include <BRep_Tool.hxx>
-#include <TCollection_AsciiString.hxx>
-#include <OSD.hxx>
-#include <BRepPrimAPI_MakeSphere.hxx>
-#include <BRepPrimAPI_MakeCylinder.hxx>
-#include <BRepPrimAPI_MakeBox.hxx>
 
 
 #ifdef WIN32
@@ -54,6 +55,7 @@
  #include <process.h>
 #else
  #include <dlfcn.h>
+ #include <libgen.h> // for basename function
 #endif
 
 #ifdef WIN32
  #define LoadLib( name ) LoadLibrary( name )
  #define GetProc GetProcAddress
  #define UnLoadLib( handle ) FreeLibrary( handle );
-#else
+#else // WIN32
  #define LibHandle void*
- #define LoadLib( name ) dlopen( name, RTLD_LAZY )
+ #ifdef DYNLOAD_LOCAL
+  #define LoadLib( name ) dlopen( name, RTLD_LAZY | RTLD_LOCAL )
+ #else // DYNLOAD_LOCAL
+  #define LoadLib( name ) dlopen( name, RTLD_LAZY | RTLD_GLOBAL )
+ #endif // DYNLOAD_LOCAL
  #define GetProc dlsym
  #define UnLoadLib( handle ) dlclose( handle );
-#endif
+#endif // WIN32
 
 #include "SMESH_Gen_i.hxx"
 #include "SMESH_version.h"
@@ -285,7 +291,6 @@ SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr            orb,
                           const char*               interfaceName )
   : Engines_Component_i( orb, poa, contId, instanceName, interfaceName )
 {
-  MESSAGE( "SMESH_Gen_i::SMESH_Gen_i : standard constructor" );
 
   myOrb = CORBA::ORB::_duplicate(orb);
   myPoa = PortableServer::POA::_duplicate(poa);
@@ -335,8 +340,6 @@ SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr            orb,
 
 SMESH_Gen_i::~SMESH_Gen_i()
 {
-  MESSAGE( "SMESH_Gen_i::~SMESH_Gen_i" );
-
   // delete hypothesis creators
   map<string, GenericHypothesisCreator_i*>::iterator itHyp, itHyp2;
   for (itHyp = myHypCreatorMap.begin(); itHyp != myHypCreatorMap.end(); itHyp++)
@@ -385,8 +388,10 @@ GenericHypothesisCreator_i* SMESH_Gen_i::getHypothesisCreator(const char* theHyp
         !strcmp( theLibName+libNameLen-3, ".so" ))
     {
       //the old format
-#ifdef WIN32
+#if defined(WIN32)
       aPlatformLibName = std::string( theLibName+3, libNameLen-6 ) + ".dll";
+#elif defined(__APPLE__)
+      aPlatformLibName = std::string( theLibName, libNameLen-3 ) + ".dylib";
 #else
       aPlatformLibName = theLibName;
 #endif
@@ -394,11 +399,13 @@ GenericHypothesisCreator_i* SMESH_Gen_i::getHypothesisCreator(const char* theHyp
     else
     {
       //try to use new format
-#ifdef WIN32
+#if defined(WIN32)
       aPlatformLibName = theLibName;
       aPlatformLibName += ".dll";
+#elif defined(__APPLE__)
+      aPlatformLibName = std::string( "lib" ) + std::string( theLibName ) + ".dylib";
 #else
-      aPlatformLibName = "lib" + std::string( theLibName ) + ".so";
+      aPlatformLibName = std::string( "lib" ) + std::string( theLibName ) + ".so";
 #endif
     }
   }
@@ -419,7 +426,7 @@ GenericHypothesisCreator_i* SMESH_Gen_i::getHypothesisCreator(const char* theHyp
       LibHandle libHandle = LoadLib( aPlatformLibName.c_str() );
       if (!libHandle)
       {
-        // report any error, if occured
+        // report any error, if occurred
 #ifndef WIN32
         const char* anError = dlerror();
         throw(SALOME_Exception(anError));
@@ -512,7 +519,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh()
     // create a new mesh object servant, store it in a map in study context
     SMESH_Mesh_i* meshServant = new SMESH_Mesh_i( GetPOA(), this, GetCurrentStudyID() );
     // create a new mesh object
-    MESSAGE("myIsEmbeddedMode " << myIsEmbeddedMode);
+    if(MYDEBUG) MESSAGE("myIsEmbeddedMode " << myIsEmbeddedMode);
     meshServant->SetImpl( myGen.CreateMesh( GetCurrentStudyID(), myIsEmbeddedMode ));
 
     // activate the CORBA servant of Mesh
@@ -571,7 +578,6 @@ void SMESH_Gen_i::SetGeomEngine( GEOM::GEOM_Gen_ptr geomcompo )
 void SMESH_Gen_i::SetEmbeddedMode( CORBA::Boolean theMode )
 {
   myIsEmbeddedMode = theMode;
-  MESSAGE("myIsEmbeddedMode " << myIsEmbeddedMode);
 
   if ( !myIsEmbeddedMode ) {
     //PAL10867: disable signals catching with "noexcepthandler" option
@@ -880,10 +886,17 @@ CORBA::Boolean SMESH_Gen_i::GetSoleSubMeshUsingHyp( SMESH::SMESH_Hypothesis_ptr
     {
       if ( !foundMesh->_is_nil() ) // not a sole mesh
       {
-        GEOM::GEOM_Object_var s1 = mesh_i   ->GetShapeToMesh();
-        GEOM::GEOM_Object_var s2 = foundMesh->GetShapeToMesh();
-        if ( ! ( isSole = s1->IsSame( s2 )))
-          break;
+        if ( !foundMesh->HasShapeToMesh() ||
+             !mesh_i   ->HasShapeToMesh() )
+        {
+          isSole = ( foundMesh->HasShapeToMesh() == mesh_i->HasShapeToMesh() );
+        }
+        else
+        {
+          GEOM::GEOM_Object_var s1 = mesh_i   ->GetShapeToMesh();
+          GEOM::GEOM_Object_var s2 = foundMesh->GetShapeToMesh();
+          isSole = s1->IsSame( s2 );
+        }
       }
       foundMesh = SMESH::SMESH_Mesh::_narrow( obj );
     }
@@ -957,16 +970,16 @@ void SMESH_Gen_i::SetOption(const char* name, const char* value)
     {
       vector<int> color;
       string str = value;
-      // color must be presented as a string of next form:
+      // color must be presented as a string of following form:
       if ( str.at(0) == '#' && str.length() == 7 ) { // hexadecimal color ("#ffaa00", for example)
         str = str.substr(1);
         for ( size_t i = 0; i < str.length()/2; i++ )
           if ( str.at(i*2) >= '0' && str.at(i*2) <= 'f' && str.at(i*2+1) >= '0' && str.at(i*2+1) <= 'f' )
             color.push_back( strtol( str.substr( i*2, 2 ).c_str(), NULL, 16 ) );
       }
-      else { // rgb color ("255,170,0", for example)
-        char* tempValue = strdup( value );
-        char* colorValue = strtok( tempValue, "," );
+      else if ( value ) { // rgb color ("255,170,0", for example)
+        string tempValue( value );
+        char* colorValue = strtok( &tempValue[0], "," );
         while ( colorValue != NULL ) {
           int c_value = atoi( colorValue );
           if ( c_value >= 0 && c_value <= 255 )
@@ -1166,7 +1179,7 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMEDorSAUV( const char* theFileNa
   _splitpath( theFileNameForPython, NULL, NULL, bname, NULL );
   string aFileName = bname;
 #else
-  string aFileName = basename( theFileNameForPython );
+  string aFileName = basename( const_cast<char *>(theFileNameForPython) );
 #endif
   // Retrieve mesh names from the file
   DriverMED_R_SMESHDS_Mesh myReader;
@@ -1209,11 +1222,11 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMEDorSAUV( const char* theFileNa
         // - as names of meshes are stored in MED file, we use them for data publishing
         // - as mesh name is not stored in UNV file, we use file name as name of mesh when publishing data
         aSO = PublishMesh( myCurrentStudy, mesh.in(), ( theFileName == theFileNameForPython ) ? (*it).c_str() : aFileName.c_str() );
+
+      // Python Dump
       if ( !aSO->_is_nil() ) {
-        // Python Dump
         aPythonDump << aSO;
       } else {
-        // Python Dump
         aPythonDump << "mesh_" << i;
       }
 
@@ -1315,7 +1328,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromSTL( const char* theFileName
   _splitpath( theFileName, NULL, NULL, bname, NULL );
   string aFileName = bname;
 #else
-  string aFileName = basename( theFileName );
+  string aFileName = basename( const_cast<char *>(theFileName) );
 #endif
   // publish mesh in the study
   if ( CanPublishInStudy( aMesh ) ) {
@@ -1444,7 +1457,7 @@ SMESH_Gen_i::CreateMeshesFromGMF( const char*             theFileName,
   _splitpath( theFileName, NULL, NULL, bname, NULL );
   string aFileName = bname;
 #else
-  string aFileName = basename( theFileName );
+  string aFileName = basename( const_cast<char *>(theFileName) );
 #endif
   // publish mesh in the study
   if ( CanPublishInStudy( aMesh ) ) {
@@ -1920,8 +1933,11 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
         myLocShape = SMESH_Mesh::PseudoShape();
       // call implementation compute
       ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
-      myGen.PrepareCompute( myLocMesh, myLocShape);
-      bool ok = myGen.Compute( myLocMesh, myLocShape);
+      myGen.PrepareCompute( myLocMesh, myLocShape );
+      int how = ::SMESH_Gen::COMPACT_MESH;
+      if ( myLocShape != myLocMesh.GetShapeToMesh() ) // compute a sub-mesh
+        how |= ::SMESH_Gen::SHAPE_ONLY;
+      bool ok = myGen.Compute( myLocMesh, myLocShape, how );
       meshServant->CreateGroupServants(); // algos can create groups (issue 0020918)
       myLocMesh.GetMeshDS()->Modified();
       return ok;
@@ -2005,7 +2021,7 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh
       ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
       TSetOfInt shapeIds;
       ::MeshDimension aDim = (MeshDimension)theDimension;
-      if ( myGen.Compute( myLocMesh, myLocShape, false, false, aDim, &shapeIds ) )
+      if ( myGen.Compute( myLocMesh, myLocShape, ::SMESH_Gen::COMPACT_MESH, aDim, &shapeIds ) )
       {
         int nbShapeId = shapeIds.size();
         theShapesId.length( nbShapeId );
@@ -2547,9 +2563,9 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray,
 
         // make a group name
         const char* typeNames[] = { "All","Nodes","Edges","Faces","Volumes","0DElems","Balls" };
-        { // check of typeNames, compilation failure mains that NB_ELEMENT_TYPES changed:
+        { // check of typeNames: compilation failure mains that NB_ELEMENT_TYPES changed:
           const int nbNames = sizeof(typeNames) / sizeof(const char*);
-          int _assert[( nbNames == SMESH::NB_ELEMENT_TYPES ) ? 1 : -1 ]; _assert[0]=0;
+          int _assert[( nbNames == SMESH::NB_ELEMENT_TYPES ) ? 2 : -1 ]; _assert[0]=_assert[1]=0;
         }
         string groupName = "Gr";
         SALOMEDS::SObject_wrap aMeshSObj = ObjectToSObject( myCurrentStudy, theMeshesArray[i] );
@@ -2957,8 +2973,19 @@ CORBA::Boolean SMESH_Gen_i::GetMEDVersion(const char* theFileName,
   theVersion = SMESH::MED_V2_1;
   MED::EVersion aVersion = MED::GetVersionId( theFileName );
   switch( aVersion ) {
-    case MED::eV2_1     : theVersion = SMESH::MED_V2_1; return true;
-    case MED::eV2_2     : theVersion = SMESH::MED_V2_2; return true;
+    case MED::eV2_1     : theVersion = SMESH::MED_V2_1;    return true;
+    case MED::eV2_2     : theVersion = SMESH::MED_V2_2;    return true;
+    case MED::eLATEST   : theVersion = SMESH::MED_LATEST;  return true;
+    case MED::eMINOR_0  : theVersion = SMESH::MED_MINOR_0; return true;
+    case MED::eMINOR_1  : theVersion = SMESH::MED_MINOR_1; return true;
+    case MED::eMINOR_2  : theVersion = SMESH::MED_MINOR_2; return true;
+    case MED::eMINOR_3  : theVersion = SMESH::MED_MINOR_3; return true;
+    case MED::eMINOR_4  : theVersion = SMESH::MED_MINOR_4; return true;
+    case MED::eMINOR_5  : theVersion = SMESH::MED_MINOR_5; return true;
+    case MED::eMINOR_6  : theVersion = SMESH::MED_MINOR_6; return true;
+    case MED::eMINOR_7  : theVersion = SMESH::MED_MINOR_7; return true;
+    case MED::eMINOR_8  : theVersion = SMESH::MED_MINOR_8; return true;
+    case MED::eMINOR_9  : theVersion = SMESH::MED_MINOR_9; return true;
     case MED::eVUnknown : return false;
   }
   return false;
@@ -3131,7 +3158,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
               if( libname_len > 4 )
                 libname.resize( libname_len - 4 );
 #else
-              // PAL17753 (Regresion: missing hypothesis in restored study)
+              // PAL17753 (Regression: missing hypothesis in restored study)
               // "lib" also should be removed from the beginning
               //if( libname_len > 3 )
                 //libname.resize( libname_len - 3 );
@@ -3200,7 +3227,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
               if( libname_len > 4 )
                 libname.resize( libname_len - 4 );
 #else
-              // PAL17753 (Regresion: missing hypothesis in restored study)
+              // PAL17753 (Regression: missing hypothesis in restored study)
               // "lib" also should be removed from the beginning
               //if( libname_len > 3 )
                 //libname.resize( libname_len - 3 );
@@ -4489,7 +4516,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
 
       // --> try to find SUB-MESHES containers for each type of submesh
       for ( int j = GetSubMeshOnVertexTag(); j <= GetSubMeshOnCompoundTag(); j++ ) {
-        const char* name_meshgroup;
+        const char* name_meshgroup = 0;
         if ( j == GetSubMeshOnVertexTag() )
           name_meshgroup = "SubMeshes On Vertex";
         else if ( j == GetSubMeshOnEdgeTag() )
@@ -4656,18 +4683,23 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
         if ( aTopGroup->ExistInternalObject( name_group ) ) {
           aGroup = new HDFgroup( name_group, aTopGroup );
           aGroup->OpenOnDisk();
-          // get number of groups
-          int aNbSubObjects = aGroup->nInternalObjects();
-          for ( int j = 0; j < aNbSubObjects; j++ ) {
-            char name_dataset[ HDF_NAME_MAX_LEN+1 ];
-            aGroup->InternalObjectIndentify( j, name_dataset );
-            // check if it is an group
-            if ( string( name_dataset ).substr( 0, 5 ) == string( "Group" ) ) {
+          // PAL23514: get all names from the HDFgroup to avoid iteration on its contents
+          // within aGroup->ExistInternalObject( name )
+          std::vector< std::string > subNames;
+          TColStd_MapOfAsciiString mapOfNames;
+          aGroup->GetAllObjects( subNames );
+          for ( size_t iN = 0; iN < subNames.size(); ++iN )
+            mapOfNames.Add( subNames[ iN ].c_str() );
+          // loop on groups
+          for ( size_t j = 0; j < subNames.size(); j++ ) {
+            const std::string& name_dataset = subNames[ j ];
+            // check if it is a group
+            if ( name_dataset.substr( 0, 5 ) == "Group" ) {
               // --> get group id
-              int subid = atoi( string( name_dataset ).substr( 5 ).c_str() );
+              int subid = atoi( name_dataset.substr( 5 ).c_str() );
               if ( subid <= 0 )
                 continue;
-              aDataset = new HDFdataset( name_dataset, aGroup );
+              aDataset = new HDFdataset( name_dataset.c_str(), aGroup );
               aDataset->OpenOnDisk();
 
               // Retrieve actual group name
@@ -4680,7 +4712,8 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
               TopoDS_Shape aShape;
               char aRefName[ 30 ];
               sprintf( aRefName, "Ref on shape %d", subid);
-              if ( aGroup->ExistInternalObject( aRefName ) ) {
+              if ( mapOfNames.Contains( aRefName ))
+              {
                 // load mesh "Ref on shape" - it's an entry to SObject
                 aDataset = new HDFdataset( aRefName, aGroup );
                 aDataset->OpenOnDisk();
@@ -4701,8 +4734,8 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
               // Try to read a filter of SMESH_GroupOnFilter
               SMESH::Filter_var filter;
               SMESH_PredicatePtr predicate;
-              std::string hdfGrpName = "Filter " + SMESH_Comment(subid);
-              if ( aGroup->ExistInternalObject( hdfGrpName.c_str() ))
+              std::string hdfGrpName = ( SMESH_Comment( "Filter ") << subid );
+              if ( mapOfNames.Contains( hdfGrpName.c_str() ))
               {
                 aDataset = new HDFdataset( hdfGrpName.c_str(), aGroup );
                 aDataset->OpenOnDisk();
@@ -4743,13 +4776,13 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
               if ( !aGroupBaseDS )
                 continue;
 
-              aGroupBaseDS->SetStoreName( name_dataset );
+              aGroupBaseDS->SetStoreName( name_dataset.c_str() );
 
               // ouv : NPAL12872
               // Read color of the group
               char aGroupColorName[ 30 ];
               sprintf( aGroupColorName, "ColorGroup %d", subid);
-              if ( aGroup->ExistInternalObject( aGroupColorName ) )
+              if ( mapOfNames.Contains( aGroupColorName ))
               {
                 aDataset = new HDFdataset( aGroupColorName, aGroup );
                 aDataset->OpenOnDisk();