Salome HOME
Movement of examples to CVS EXAMPLES SAMPLES_SRC.
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_HypothesesUtils.cxx
1 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 //
4 //  This library is free software; you can redistribute it and/or
5 //  modify it under the terms of the GNU Lesser General Public
6 //  License as published by the Free Software Foundation; either
7 //  version 2.1 of the License.
8 //
9 //  This library is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 //  Lesser General Public License for more details.
13 //
14 //  You should have received a copy of the GNU Lesser General Public
15 //  License along with this library; if not, write to the Free Software
16 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
19
20 #include "SMESHGUI_HypothesesUtils.h"
21
22 #include "SMESHGUI.h"
23 #include "SMESHGUI_Hypotheses.h"
24 #include "SMESHGUI_XmlHandler.h"
25 #include "SMESHGUI_Utils.h"
26 #include "SMESHGUI_GEOMGenUtils.h"
27
28 #include "SUIT_Tools.h"
29 #include "SUIT_Desktop.h"
30 #include "SUIT_MessageBox.h"
31 #include "SUIT_OverrideCursor.h"
32 #include "SUIT_ResourceMgr.h"
33 #include "SUIT_Session.h"
34
35 #include "OB_Browser.h"
36
37 #include "SalomeApp_Study.h"
38 #include "SalomeApp_Tools.h"
39 #include "SalomeApp_Application.h"
40
41 #include <SALOMEDSClient_Study.hxx>
42 #include <SALOMEDSClient_SObject.hxx>
43
44 #include "SALOMEconfig.h"
45 #include CORBA_CLIENT_HEADER(SALOMEDS_Attributes)
46
47 #include <map>
48 #include <string>
49
50 #include <dlfcn.h>
51
52 #ifdef _DEBUG_
53 static int MYDEBUG = 0;
54 #else
55 static int MYDEBUG = 0;
56 #endif
57
58 namespace SMESH{
59
60   using namespace std;
61
62   typedef map<string,HypothesisData*> THypothesisDataMap;
63   THypothesisDataMap myHypothesesMap;
64   THypothesisDataMap myAlgorithmsMap;
65
66   typedef map<string,SMESHGUI_GenericHypothesisCreator*> THypCreatorMap;
67   THypCreatorMap myHypCreatorMap;
68
69   void addMap(const THypothesisDataMap& theMap,
70                THypothesisDataMap& toMap)
71   {
72     THypothesisDataMap::const_iterator it;
73     for (it = theMap.begin(); it != theMap.end(); it++)
74       toMap.insert(*it);
75   }
76
77
78   void processHypothesisStatus(const int theHypStatus,
79                                SMESH::SMESH_Hypothesis_ptr theHyp,
80                                const bool theIsAddition)
81   {
82     if (theHypStatus > SMESH::HYP_OK) {
83
84       // get Hyp name
85       QString aHypName ("NULL Hypothesis");
86       if (!CORBA::is_nil(theHyp)) {
87         _PTR(SObject) Shyp = SMESH::FindSObject(theHyp);
88         if (Shyp)
89           // name in study
90           aHypName = Shyp->GetName().c_str();
91         else
92           // label in xml file
93           aHypName = GetHypothesisData(theHyp->GetName())->Label;
94       }
95
96       // message
97       bool isFatal = (theHypStatus >= SMESH::HYP_UNKNOWN_FATAL);
98       QString aMsg;
99       if (theIsAddition)
100         aMsg = (isFatal ? "SMESH_CANT_ADD_HYP" : "SMESH_ADD_HYP_WRN");
101       else
102         aMsg = (isFatal ? "SMESH_CANT_RM_HYP"  : "SMESH_RM_HYP_WRN");
103
104       aMsg = QObject::tr(aMsg).arg(aHypName) +
105         QObject::tr(QString("SMESH_HYP_%1").arg(theHypStatus));
106
107       SUIT_MessageBox::warn1(SMESHGUI::desktop(),
108                             QObject::tr("SMESH_WRN_WARNING"),
109                             aMsg,
110                             QObject::tr("SMESH_BUT_OK"));
111     }
112   }
113
114
115   void InitAvailableHypotheses()
116   {
117     SUIT_OverrideCursor wc;
118     if (myHypothesesMap.empty() && myAlgorithmsMap.empty()) {
119       // Resource manager
120       SUIT_ResourceMgr* resMgr = SMESHGUI::resourceMgr();
121       if (!resMgr) return;
122
123       // Find name of a resource XML file ("SMESH_Meshers.xml");
124       QString HypsXml;
125       char* cenv = getenv("SMESH_MeshersList");
126       if (cenv)
127         HypsXml.sprintf("%s", cenv);
128
129       QStringList HypsXmlList = QStringList::split(":", HypsXml, false);
130       if (HypsXmlList.count() == 0)
131         {
132           SUIT_MessageBox::error1(SMESHGUI::desktop(),
133                                  QObject::tr("SMESH_WRN_WARNING"),
134                                  QObject::tr("MESHERS_FILE_NO_VARIABLE"),
135                                  QObject::tr("SMESH_BUT_OK"));
136           return;
137         }
138
139       // loop on files in HypsXml
140       QString aNoAccessFiles;
141       for (int i = 0; i < HypsXmlList.count(); i++) {
142         QString HypsXml = HypsXmlList[ i ];
143
144         // Find full path to the resource XML file
145         QString xmlFile = resMgr->path("resources", "SMESH", HypsXml + ".xml");
146         if ( xmlFile.isEmpty() ) // try PLUGIN resources
147           xmlFile = resMgr->path("resources", HypsXml, HypsXml + ".xml");
148         
149         QFile file (xmlFile);
150         if (file.exists() && file.open(IO_ReadOnly)) {
151           file.close();
152
153           SMESHGUI_XmlHandler* aXmlHandler = new SMESHGUI_XmlHandler();
154           ASSERT(aXmlHandler);
155
156           QXmlInputSource source (file);
157           QXmlSimpleReader reader;
158           reader.setContentHandler(aXmlHandler);
159           reader.setErrorHandler(aXmlHandler);
160           bool ok = reader.parse(source);
161           file.close();
162           if (ok) {
163             addMap(aXmlHandler->myHypothesesMap, myHypothesesMap);
164             addMap(aXmlHandler->myAlgorithmsMap, myAlgorithmsMap);
165           }
166           else {
167             SUIT_MessageBox::error1(SMESHGUI::desktop(),
168                                    QObject::tr("INF_PARSE_ERROR"),
169                                    QObject::tr(aXmlHandler->errorProtocol()),
170                                    QObject::tr("SMESH_BUT_OK"));
171           }
172         }
173         else {
174           if (aNoAccessFiles.isEmpty())
175             aNoAccessFiles = xmlFile;
176           else
177             aNoAccessFiles += ", " + xmlFile;
178         }
179       } // end loop
180
181
182       if (!aNoAccessFiles.isEmpty()) {
183         QString aMess = QObject::tr("MESHERS_FILE_CANT_OPEN") + " " + aNoAccessFiles + "\n";
184         aMess += QObject::tr("MESHERS_FILE_CHECK_VARIABLE");
185         wc.suspend();
186         SUIT_MessageBox::warn1(SMESHGUI::desktop(),
187                               QObject::tr("SMESH_WRN_WARNING"),
188                               aMess,
189                               QObject::tr("SMESH_BUT_OK"));
190         wc.resume();
191       }
192     }
193   }
194
195
196   QStringList GetAvailableHypotheses( const bool isAlgo, 
197                                       const int theDim,                          
198                                       const bool isAux )
199   {
200     QStringList aHypList;
201
202     // Init list of available hypotheses, if needed
203     InitAvailableHypotheses();
204
205     // fill list of hypotheses/algorithms
206     THypothesisDataMap* pMap = isAlgo ? &myAlgorithmsMap : &myHypothesesMap;
207     THypothesisDataMap::iterator anIter;
208     for ( anIter = pMap->begin(); anIter != pMap->end(); anIter++ )
209     {
210       HypothesisData* aData = (*anIter).second;
211       if ( ( theDim < 0 || aData->Dim.contains( theDim ) ) && aData->IsAux == isAux )
212         aHypList.append(((*anIter).first).c_str());
213     }
214     return aHypList;
215   }
216
217
218   HypothesisData* GetHypothesisData (const char* aHypType)
219   {
220     HypothesisData* aHypData = 0;
221
222     // Init list of available hypotheses, if needed
223     InitAvailableHypotheses();
224
225     if (myHypothesesMap.find(aHypType) == myHypothesesMap.end()) {
226       if (myAlgorithmsMap.find(aHypType) != myAlgorithmsMap.end()) {
227         aHypData = myAlgorithmsMap[aHypType];
228       }
229     }
230     else {
231       aHypData = myHypothesesMap[aHypType];
232     }
233     return aHypData;
234   }
235
236
237   SMESHGUI_GenericHypothesisCreator* GetHypothesisCreator(const char* aHypType)
238   {
239     if(MYDEBUG) MESSAGE("Get HypothesisCreator for " << aHypType);
240
241     SMESHGUI_GenericHypothesisCreator* aCreator = 0;
242
243     // check, if creator for this hypothesis type already exists
244     if (myHypCreatorMap.find(aHypType) != myHypCreatorMap.end()) {
245       aCreator = myHypCreatorMap[aHypType];
246     }
247     else {
248       // 1. Init list of available hypotheses, if needed
249       InitAvailableHypotheses();
250
251       // 2. Get names of plugin libraries
252       HypothesisData* aHypData = GetHypothesisData(aHypType);
253       if (!aHypData) 
254         return aCreator;
255       QString aClientLibName = aHypData->ClientLibName;
256       QString aServerLibName = aHypData->ServerLibName;
257
258       // 3. Load Client Plugin Library
259       try {
260         // load plugin library
261         if(MYDEBUG) MESSAGE("Loading client meshers plugin library ...");
262         void* libHandle = dlopen (aClientLibName, RTLD_LAZY);
263         if (!libHandle) {
264           // report any error, if occured
265           const char* anError = dlerror();
266           if(MYDEBUG) MESSAGE(anError);
267         }
268         else {
269           // get method, returning hypothesis creator
270           if(MYDEBUG) MESSAGE("Find GetHypothesisCreator() method ...");
271           typedef SMESHGUI_GenericHypothesisCreator* (*GetHypothesisCreator) \
272             (QString aHypType, QString aServerLibName, SMESHGUI* aSMESHGUI);
273           GetHypothesisCreator procHandle =
274             (GetHypothesisCreator)dlsym(libHandle, "GetHypothesisCreator");
275           if (!procHandle) {
276             if(MYDEBUG) MESSAGE("bad hypothesis client plugin library");
277             dlclose(libHandle);
278           }
279           else {
280             // get hypothesis creator
281             if(MYDEBUG) MESSAGE("Get Hypothesis Creator for " << aHypType);
282             aCreator = procHandle(aHypType, aServerLibName, SMESHGUI::GetSMESHGUI());
283             if (!aCreator) {
284               if(MYDEBUG) MESSAGE("no such a hypothesis in this plugin");
285             }
286             else {
287               // map hypothesis creator to a hypothesis name
288               myHypCreatorMap[aHypType] = aCreator;
289             }
290           }
291         }
292       }
293       catch (const SALOME::SALOME_Exception& S_ex) {
294         SalomeApp_Tools::QtCatchCorbaException(S_ex);
295       }
296     }
297
298     return aCreator;
299   }
300
301
302   SMESH::SMESH_Hypothesis_ptr CreateHypothesis(const char* aHypType,
303                                                const char* aHypName,
304                                                const bool isAlgo)
305   {
306     if(MYDEBUG) MESSAGE("Create " << aHypType << " with name " << aHypName);
307
308     SMESH::SMESH_Hypothesis_var Hyp;
309
310     HypothesisData* aHypData = GetHypothesisData(aHypType);
311     QString aServLib = aHypData->ServerLibName;
312
313     try {
314       Hyp = SMESHGUI::GetSMESHGen()->CreateHypothesis(aHypType, aServLib);
315       if (!Hyp->_is_nil()) {
316         _PTR(SObject) SHyp = SMESH::FindSObject(Hyp.in());
317         if (SHyp) {
318           //if (strcmp(aHypName,"") != 0)
319           if (strlen(aHypName) > 0)
320             SMESH::SetName(SHyp, aHypName);
321           //SalomeApp_Application* app =
322           //  dynamic_cast<SalomeApp_Application*>(SUIT_Session::session()->activeApplication());
323           //if (app)
324           //  app->objectBrowser()->updateTree();
325           SMESHGUI::GetSMESHGUI()->updateObjBrowser();
326           return Hyp._retn();
327         }
328       }
329     }
330     catch (const SALOME::SALOME_Exception & S_ex) {
331       SalomeApp_Tools::QtCatchCorbaException(S_ex);
332     }
333
334     return SMESH::SMESH_Hypothesis::_nil();
335   }
336
337
338   bool AddHypothesisOnMesh (SMESH::SMESH_Mesh_ptr aMesh, SMESH::SMESH_Hypothesis_ptr aHyp)
339   {
340     if(MYDEBUG) MESSAGE ("SMESHGUI::AddHypothesisOnMesh");
341     int res = SMESH::HYP_UNKNOWN_FATAL;
342     SUIT_OverrideCursor wc;
343
344     if (!aMesh->_is_nil()) {
345       _PTR(SObject) SM = SMESH::FindSObject(aMesh);
346       GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(SM);
347       try {
348         res = aMesh->AddHypothesis(aShapeObject, aHyp);
349         if (res < SMESH::HYP_UNKNOWN_FATAL) {
350           _PTR(SObject) SH = SMESH::FindSObject(aHyp);
351           if (SM && SH) {
352             SMESH::ModifiedMesh(SM, false);
353           }
354         }
355         if (res > SMESH::HYP_OK) {
356           wc.suspend();
357           processHypothesisStatus(res, aHyp, true);
358           wc.resume();
359         }
360       }
361       catch(const SALOME::SALOME_Exception& S_ex) {
362         wc.suspend();
363         SalomeApp_Tools::QtCatchCorbaException(S_ex);
364         res = SMESH::HYP_UNKNOWN_FATAL;
365       }
366     }
367     return res < SMESH::HYP_UNKNOWN_FATAL;
368   }
369
370
371   bool AddHypothesisOnSubMesh (SMESH::SMESH_subMesh_ptr aSubMesh, SMESH::SMESH_Hypothesis_ptr aHyp)
372   {
373     if(MYDEBUG) MESSAGE("SMESHGUI::AddHypothesisOnSubMesh() ");
374     int res = SMESH::HYP_UNKNOWN_FATAL;
375     SUIT_OverrideCursor wc;
376
377     if (!aSubMesh->_is_nil() && ! aHyp->_is_nil()) {
378       try {
379         SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
380         _PTR(SObject) SsubM = SMESH::FindSObject(aSubMesh);
381         GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(SsubM);
382         if (!aMesh->_is_nil() && SsubM && !aShapeObject->_is_nil()) {
383           res = aMesh->AddHypothesis(aShapeObject, aHyp);
384           if (res < SMESH::HYP_UNKNOWN_FATAL)  {
385             _PTR(SObject) meshSO = SMESH::FindSObject(aMesh);
386             if (meshSO)
387               SMESH::ModifiedMesh(meshSO, false);
388           }
389           if (res > SMESH::HYP_OK) {
390             wc.suspend();
391             processHypothesisStatus(res, aHyp, true);
392             wc.resume();
393           }
394         }
395         else {
396           SCRUTE(aHyp->_is_nil());
397           SCRUTE(aMesh->_is_nil());
398           SCRUTE(!SsubM);
399           SCRUTE(aShapeObject->_is_nil());
400         }
401       }
402       catch(const SALOME::SALOME_Exception& S_ex) {
403         wc.suspend();
404         SalomeApp_Tools::QtCatchCorbaException(S_ex);
405         res = SMESH::HYP_UNKNOWN_FATAL;
406       }
407     }
408     else {
409       SCRUTE(aSubMesh->_is_nil());
410       SCRUTE(aHyp->_is_nil());
411     }
412     return res < SMESH::HYP_UNKNOWN_FATAL;
413   }
414
415   bool RemoveHypothesisOrAlgorithmOnMesh (const Handle(SALOME_InteractiveObject)& IObject)
416   {
417     int res = SMESH::HYP_UNKNOWN_FATAL;
418     SUIT_OverrideCursor wc;
419
420     try {
421       _PTR(Study) aStudy = GetActiveStudyDocument();
422       _PTR(SObject) aHypObj = aStudy->FindObjectID( IObject->getEntry() );
423       if( aHypObj )
424       {
425         _PTR(SObject) MorSM = SMESH::GetMeshOrSubmesh( aHypObj );
426         _PTR(SObject) aRealHypo;
427         if( aHypObj->ReferencedObject( aRealHypo ) )
428         {
429           SMESH_Hypothesis_var hypo = SMESH_Hypothesis::_narrow( SObjectToObject( aRealHypo ) );
430           RemoveHypothesisOrAlgorithmOnMesh( MorSM, hypo );
431         }
432         else
433         {
434           SMESH_Hypothesis_var hypo = SMESH_Hypothesis::_narrow( SObjectToObject( aHypObj ) );
435           SObjectList meshList = GetMeshesUsingAlgoOrHypothesis( hypo );
436           for( int i = 0; i < meshList.size(); i++ )
437             RemoveHypothesisOrAlgorithmOnMesh( meshList[ i ], hypo );
438         }
439       }
440     }
441     catch(const SALOME::SALOME_Exception& S_ex)
442     {
443       wc.suspend();
444       SalomeApp_Tools::QtCatchCorbaException(S_ex);
445       res = SMESH::HYP_UNKNOWN_FATAL;
446     }
447     return res < SMESH::HYP_UNKNOWN_FATAL;
448   }
449
450   bool RemoveHypothesisOrAlgorithmOnMesh (_PTR(SObject) MorSM,
451                                           SMESH::SMESH_Hypothesis_ptr anHyp)
452   {
453     SALOMEDS::GenericAttribute_var anAttr;
454     SALOMEDS::AttributeIOR_var anIOR;
455     int res = SMESH::HYP_UNKNOWN_FATAL;
456     SUIT_OverrideCursor wc;
457
458     if (MorSM) {
459       try {
460         GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(MorSM);
461         if (!aShapeObject->_is_nil()) {
462           SMESH::SMESH_Mesh_var aMesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>(MorSM);
463           SMESH::SMESH_subMesh_var aSubMesh = SMESH::SObjectToInterface<SMESH::SMESH_subMesh>(MorSM);
464
465           if (!aSubMesh->_is_nil())
466             aMesh = aSubMesh->GetFather();
467
468           if (!aMesh->_is_nil()) {
469             res = aMesh->RemoveHypothesis(aShapeObject, anHyp);
470             if (res < SMESH::HYP_UNKNOWN_FATAL) {
471               _PTR(SObject) meshSO = SMESH::FindSObject(aMesh);
472               if (meshSO)
473                 SMESH::ModifiedMesh(meshSO, false);
474             }
475             if (res > SMESH::HYP_OK) {
476               wc.suspend();
477               processHypothesisStatus(res, anHyp, false);
478               wc.resume();
479             }
480           }
481         }
482       } catch(const SALOME::SALOME_Exception& S_ex) {
483         wc.suspend();
484         SalomeApp_Tools::QtCatchCorbaException(S_ex);
485         res = SMESH::HYP_UNKNOWN_FATAL;
486       }
487     }
488     return res < SMESH::HYP_UNKNOWN_FATAL;
489   }
490
491   SObjectList GetMeshesUsingAlgoOrHypothesis(SMESH::SMESH_Hypothesis_ptr AlgoOrHyp)
492   {
493     SObjectList listSOmesh;
494     listSOmesh.resize(0);
495
496     unsigned int index = 0;
497     if (!AlgoOrHyp->_is_nil()) {
498       _PTR(SObject) SO_Hypothesis = SMESH::FindSObject(AlgoOrHyp);
499       if (SO_Hypothesis) {
500         SObjectList listSO =
501           SMESHGUI::activeStudy()->studyDS()->FindDependances(SO_Hypothesis);
502
503         if(MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency number ="<<listSO.size());
504         for (unsigned int i = 0; i < listSO.size(); i++) {
505           _PTR(SObject) SO = listSO[i];
506           if (SO) {
507             _PTR(SObject) aFather = SO->GetFather();
508             if (aFather) {
509               _PTR(SObject) SOfatherFather = aFather->GetFather();
510               if (SOfatherFather) {
511                 if(MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency added to list");
512                 index++;
513                 listSOmesh.resize(index);
514                 listSOmesh[index - 1] = SOfatherFather;
515               }
516             }
517           }
518         }
519       }
520     }
521     if (MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): completed");
522     return listSOmesh;
523   }
524 }