Salome HOME
PAL16617 (Modification/Transformation operations with copy don't create a new mesh)
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_HypothesesUtils.cxx
index 75fde54b194d956fb5dfdfe53444a06156fb20e7..119406be5c283b59ed859f7cbe69bc475c7fde5a 100644 (file)
@@ -15,7 +15,7 @@
 //  License along with this library; if not, write to the Free Software
 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 
 #include "SMESHGUI_HypothesesUtils.h"
 
 #include <map>
 #include <string>
 
-#include <dlfcn.h>
+#ifdef WNT
+ #include <windows.h>
+#else
+ #include <dlfcn.h>
+#endif
+
+#ifdef WNT
+ #define LibHandle HMODULE
+ #define LoadLib( name ) LoadLibrary( name )
+ #define GetProc GetProcAddress
+ #define UnLoadLib( handle ) FreeLibrary( handle );
+#else
+ #define LibHandle void*
+ #define LoadLib( name ) dlopen( name, RTLD_LAZY )
+ #define GetProc dlsym
+ #define UnLoadLib( handle ) dlclose( handle );
+#endif
 
 #ifdef _DEBUG_
 static int MYDEBUG = 0;
@@ -66,14 +82,7 @@ namespace SMESH{
   typedef map<string,SMESHGUI_GenericHypothesisCreator*> THypCreatorMap;
   THypCreatorMap myHypCreatorMap;
 
-  void addMap(const THypothesisDataMap& theMap,
-              THypothesisDataMap& toMap)
-  {
-    THypothesisDataMap::const_iterator it;
-    for (it = theMap.begin(); it != theMap.end(); it++)
-      toMap.insert(*it);
-  }
-
+  list<HypothesesSet*> myListOfHypothesesSets;
 
   void processHypothesisStatus(const int theHypStatus,
                               SMESH::SMESH_Hypothesis_ptr theHyp,
@@ -160,8 +169,12 @@ namespace SMESH{
          bool ok = reader.parse(source);
          file.close();
          if (ok) {
-           addMap(aXmlHandler->myHypothesesMap, myHypothesesMap);
-           addMap(aXmlHandler->myAlgorithmsMap, myAlgorithmsMap);
+            myHypothesesMap.insert( aXmlHandler->myHypothesesMap.begin(),
+                                    aXmlHandler->myHypothesesMap.end() );
+            myAlgorithmsMap.insert( aXmlHandler->myAlgorithmsMap.begin(),
+                                    aXmlHandler->myAlgorithmsMap.end() );
+            myListOfHypothesesSets.splice( myListOfHypothesesSets.begin(),
+                                           aXmlHandler->myListOfHypothesesSets );
          }
          else {
            SUIT_MessageBox::error1(SMESHGUI::desktop(),
@@ -193,31 +206,64 @@ namespace SMESH{
   }
 
 
-  QStringList GetAvailableHypotheses(const bool isAlgo)
+  QStringList GetAvailableHypotheses( const bool isAlgo, 
+                                      const int theDim,                          
+                                      const bool isAux,
+                                      const bool isNeedGeometry)
   {
     QStringList aHypList;
 
     // Init list of available hypotheses, if needed
     InitAvailableHypotheses();
-
+    bool checkGeometry = !isNeedGeometry;
     // fill list of hypotheses/algorithms
+    THypothesisDataMap* pMap = isAlgo ? &myAlgorithmsMap : &myHypothesesMap;
     THypothesisDataMap::iterator anIter;
-    if (isAlgo) {
-      anIter = myAlgorithmsMap.begin();
-      for (; anIter != myAlgorithmsMap.end(); anIter++) {
-       aHypList.append(((*anIter).first).c_str());
-      }
+    for ( anIter = pMap->begin(); anIter != pMap->end(); anIter++ )
+    {
+      HypothesisData* aData = (*anIter).second;
+      if ( ( theDim < 0 || aData->Dim.contains( theDim ) ) && aData->IsAux == isAux)
+        if (checkGeometry){
+          if (aData->IsNeedGeometry == isNeedGeometry)
+            aHypList.append(((*anIter).first).c_str());
+        }
+        else
+          aHypList.append(((*anIter).first).c_str());
     }
-    else {
-      anIter = myHypothesesMap.begin();
-      for (; anIter != myHypothesesMap.end(); anIter++) {
-       aHypList.append(((*anIter).first).c_str());
+    return aHypList;
+  }
+
+
+  QStringList GetHypothesesSets()
+  {
+    QStringList aSetNameList;
+
+    // Init list of available hypotheses, if needed
+    InitAvailableHypotheses();
+
+    list<HypothesesSet*>::iterator hypoSet = myListOfHypothesesSets.begin();
+    for ( ; hypoSet != myListOfHypothesesSets.end(); ++hypoSet )
+    {
+      HypothesesSet* aSet = *hypoSet;
+      if ( aSet && aSet->AlgoList.count() ) {
+        aSetNameList.append( aSet->HypoSetName );
       }
     }
 
-    return aHypList;
+    return aSetNameList;
   }
 
+  HypothesesSet* GetHypothesesSet(const QString theSetName)
+  {
+    list<HypothesesSet*>::iterator hypoSet = myListOfHypothesesSets.begin();
+    for ( ; hypoSet != myListOfHypothesesSets.end(); ++hypoSet )
+    {
+      HypothesesSet* aSet = *hypoSet;
+      if ( aSet && aSet->HypoSetName == theSetName )
+        return aSet;
+    }
+    return 0;
+  }
 
   HypothesisData* GetHypothesisData (const char* aHypType)
   {
@@ -226,17 +272,50 @@ namespace SMESH{
     // Init list of available hypotheses, if needed
     InitAvailableHypotheses();
 
-    if (myHypothesesMap.find(aHypType) == myHypothesesMap.end()) {
-      if (myAlgorithmsMap.find(aHypType) != myAlgorithmsMap.end()) {
-       aHypData = myAlgorithmsMap[aHypType];
-      }
+    THypothesisDataMap::iterator type_data = myHypothesesMap.find(aHypType);
+    if (type_data != myHypothesesMap.end()) {
+      aHypData = type_data->second;
     }
     else {
-      aHypData = myHypothesesMap[aHypType];
+      type_data = myAlgorithmsMap.find(aHypType);
+      if (type_data != myAlgorithmsMap.end())
+        aHypData = type_data->second;
     }
     return aHypData;
   }
 
+  bool IsAvailableHypothesis(const HypothesisData* algoData,
+                             const QString&        hypType,
+                             bool&                 isAuxiliary)
+  {
+    isAuxiliary = false;
+    if ( !algoData )
+      return false;
+    if ( algoData->NeededHypos.contains( hypType ))
+      return true;
+    if ( algoData->OptionalHypos.contains( hypType)) {
+      isAuxiliary = true;
+      return true;
+    }
+    return false;
+  }
+
+  bool IsCompatibleAlgorithm(const HypothesisData* algo1Data,
+                             const HypothesisData* algo2Data)
+  {
+    if ( !algo1Data || !algo2Data )
+      return false;
+    const HypothesisData* algoIn = algo1Data, *algoMain = algo2Data;
+    if ( algoIn->Dim.first() > algoMain->Dim.first() ) {
+      algoIn = algo2Data; algoMain = algo1Data;
+    }
+    // look for any output type of algoIn between input types of algoMain
+    QStringList::const_iterator inElemType = algoIn->OutputTypes.begin();
+    for ( ; inElemType != algoIn->OutputTypes.end(); ++inElemType )
+      if ( algoMain->InputTypes.contains( *inElemType ))
+        return true;
+    return false;
+  }
 
   SMESHGUI_GenericHypothesisCreator* GetHypothesisCreator(const char* aHypType)
   {
@@ -254,9 +333,8 @@ namespace SMESH{
 
       // 2. Get names of plugin libraries
       HypothesisData* aHypData = GetHypothesisData(aHypType);
-      if (!aHypData) {
-       return aCreator;
-      }
+      if (!aHypData) 
+        return aCreator;
       QString aClientLibName = aHypData->ClientLibName;
       QString aServerLibName = aHypData->ServerLibName;
 
@@ -264,27 +342,34 @@ namespace SMESH{
       try {
        // load plugin library
        if(MYDEBUG) MESSAGE("Loading client meshers plugin library ...");
-       void* libHandle = dlopen (aClientLibName, RTLD_LAZY);
+       LibHandle libHandle = LoadLib( aClientLibName );
        if (!libHandle) {
          // report any error, if occured
-         const char* anError = dlerror();
-         if(MYDEBUG) MESSAGE(anError);
+    if ( MYDEBUG )
+    {
+#ifdef WIN32
+      const char* anError = "Can't load client meshers plugin library";
+#else
+           const char* anError = dlerror();      
+#endif
+      MESSAGE(anError);
+    }
        }
        else {
          // get method, returning hypothesis creator
          if(MYDEBUG) MESSAGE("Find GetHypothesisCreator() method ...");
          typedef SMESHGUI_GenericHypothesisCreator* (*GetHypothesisCreator) \
-           (QString aHypType, QString aServerLibName, SMESHGUI* aSMESHGUI);
+           ( const QString& );
          GetHypothesisCreator procHandle =
-           (GetHypothesisCreator)dlsym(libHandle, "GetHypothesisCreator");
+           (GetHypothesisCreator)GetProc(libHandle, "GetHypothesisCreator");
          if (!procHandle) {
            if(MYDEBUG) MESSAGE("bad hypothesis client plugin library");
-           dlclose(libHandle);
+           UnLoadLib(libHandle);
          }
          else {
            // get hypothesis creator
            if(MYDEBUG) MESSAGE("Get Hypothesis Creator for " << aHypType);
-           aCreator = procHandle(aHypType, aServerLibName, SMESHGUI::GetSMESHGUI());
+           aCreator = procHandle( aHypType );
            if (!aCreator) {
              if(MYDEBUG) MESSAGE("no such a hypothesis in this plugin");
            }
@@ -309,30 +394,21 @@ namespace SMESH{
                                               const bool isAlgo)
   {
     if(MYDEBUG) MESSAGE("Create " << aHypType << " with name " << aHypName);
-
-    SMESH::SMESH_Hypothesis_var Hyp;
-
     HypothesisData* aHypData = GetHypothesisData(aHypType);
     QString aServLib = aHypData->ServerLibName;
-
     try {
-      Hyp = SMESHGUI::GetSMESHGen()->CreateHypothesis(aHypType, aServLib);
-      if (!Hyp->_is_nil()) {
-       _PTR(SObject) SHyp = SMESH::FindSObject(Hyp.in());
-       if (SHyp) {
-         //if (strcmp(aHypName,"") != 0)
+      SMESH::SMESH_Hypothesis_var aHypothesis;
+      aHypothesis = SMESHGUI::GetSMESHGen()->CreateHypothesis(aHypType, aServLib);
+      if (!aHypothesis->_is_nil()) {
+       _PTR(SObject) aHypSObject = SMESH::FindSObject(aHypothesis.in());
+       if (aHypSObject) {
          if (strlen(aHypName) > 0)
-           SMESH::SetName(SHyp, aHypName);
-         //SalomeApp_Application* app =
-         //  dynamic_cast<SalomeApp_Application*>(SUIT_Session::session()->activeApplication());
-         //if (app)
-         //  app->objectBrowser()->updateTree();
-          SMESHGUI::GetSMESHGUI()->updateObjBrowser();
-         return Hyp._retn();
+           SMESH::SetName(aHypSObject, aHypName);
+         SMESHGUI::GetSMESHGUI()->updateObjBrowser();
+         return aHypothesis._retn();
        }
       }
-    }
-    catch (const SALOME::SALOME_Exception & S_ex) {
+    } catch (const SALOME::SALOME_Exception & S_ex) {
       SalomeApp_Tools::QtCatchCorbaException(S_ex);
     }
 
@@ -352,9 +428,9 @@ namespace SMESH{
       try {
        res = aMesh->AddHypothesis(aShapeObject, aHyp);
        if (res < SMESH::HYP_UNKNOWN_FATAL) {
-         _PTR(SObject) SH = SMESH::FindSObject(aHyp);
-         if (SM && SH) {
-           SMESH::ModifiedMesh(SM, false);
+         _PTR(SObject) aSH = SMESH::FindSObject(aHyp);
+         if (SM && aSH) {
+           SMESH::ModifiedMesh(SM, false, aMesh->NbNodes()==0);
          }
        }
        if (res > SMESH::HYP_OK) {
@@ -389,7 +465,7 @@ namespace SMESH{
          if (res < SMESH::HYP_UNKNOWN_FATAL)  {
             _PTR(SObject) meshSO = SMESH::FindSObject(aMesh);
             if (meshSO)
-              SMESH::ModifiedMesh(meshSO, false);
+              SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0);
          }
          if (res > SMESH::HYP_OK) {
            wc.suspend();
@@ -463,27 +539,36 @@ namespace SMESH{
     if (MorSM) {
       try {
         GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(MorSM);
-        if (!aShapeObject->_is_nil()) {
-          SMESH::SMESH_Mesh_var aMesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>(MorSM);
-         SMESH::SMESH_subMesh_var aSubMesh = SMESH::SObjectToInterface<SMESH::SMESH_subMesh>(MorSM);
-
-         if (!aSubMesh->_is_nil())
-           aMesh = aSubMesh->GetFather();
-
-         if (!aMesh->_is_nil()) {
-           res = aMesh->RemoveHypothesis(aShapeObject, anHyp);
+        SMESH::SMESH_Mesh_var aMesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>(MorSM);
+        SMESH::SMESH_subMesh_var aSubMesh = SMESH::SObjectToInterface<SMESH::SMESH_subMesh>(MorSM);
+        
+        if (!aSubMesh->_is_nil())
+          aMesh = aSubMesh->GetFather();
+        
+        if (!aMesh->_is_nil()) {    
+          if (aMesh->HasShapeToMesh() && !aShapeObject->_is_nil()) {
+            res = aMesh->RemoveHypothesis(aShapeObject, anHyp);
+            if (res < SMESH::HYP_UNKNOWN_FATAL) {
+              _PTR(SObject) meshSO = SMESH::FindSObject(aMesh);
+              if (meshSO)
+                SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0);
+            }
+            
+          }
+          else if(!aMesh->HasShapeToMesh()){
+            res = aMesh->RemoveHypothesis(aShapeObject, anHyp);
            if (res < SMESH::HYP_UNKNOWN_FATAL) {
               _PTR(SObject) meshSO = SMESH::FindSObject(aMesh);
               if (meshSO)
-                SMESH::ModifiedMesh(meshSO, false);
+                SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0);              
             }
-           if (res > SMESH::HYP_OK) {
-             wc.suspend();
-             processHypothesisStatus(res, anHyp, false);
-             wc.resume();
-           }
-         }
-       }
+          }
+          if (res > SMESH::HYP_OK) {
+            wc.suspend();
+            processHypothesisStatus(res, anHyp, false);
+            wc.resume();
+          }
+        }
       } catch(const SALOME::SALOME_Exception& S_ex) {
        wc.suspend();
        SalomeApp_Tools::QtCatchCorbaException(S_ex);
@@ -526,4 +611,40 @@ namespace SMESH{
     if (MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): completed");
     return listSOmesh;
   }
+
+#define CASE2MESSAGE(enum) case SMESH::enum: msg = QObject::tr( "STATE_" #enum ); break;
+  QString GetMessageOnAlgoStateErrors(const algo_error_array& errors)
+  {
+    QString resMsg = QObject::tr("SMESH_WRN_MISSING_PARAMETERS") + ":\n";
+    for ( int i = 0; i < errors.length(); ++i ) {
+      const SMESH::AlgoStateError & error = errors[ i ];
+      const bool hasAlgo = ( strlen( error.algoName ) != 0 );
+      QString msg;
+      if ( !hasAlgo )
+        msg = QObject::tr( "STATE_ALGO_MISSING" );
+      else 
+        switch( error.state ) {
+          CASE2MESSAGE( HYP_MISSING );
+          CASE2MESSAGE( HYP_NOTCONFORM );
+          CASE2MESSAGE( HYP_BAD_PARAMETER );
+          CASE2MESSAGE( HYP_BAD_GEOMETRY );
+        default: continue;
+        }
+      // apply args to message:
+      // %1 - algo name
+      if ( hasAlgo )
+        msg = msg.arg( error.algoName.in() );
+      // %2 - dimension
+      msg = msg.arg( error.algoDim );
+      // %3 - global/local
+      msg = msg.arg( QObject::tr( error.isGlobalAlgo ? "GLOBAL_ALGO" : "LOCAL_ALGO" ));
+      // %4 - hypothesis dim == algoDim
+      msg = msg.arg( error.algoDim );
+
+      if ( i ) resMsg += ";\n";
+      resMsg += msg;
+    }
+    return resMsg;
+  }
+
 }