Salome HOME
Prevent exception at shape selection if no mesh was pre-selected
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_Hypotheses.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 <map>
21 #include <string>
22
23 #include "SMESHGUI_Hypotheses.h"
24 #include "SMESHGUI_Utils.h"
25
26 #ifdef _DEBUG_
27 static int MYDEBUG = 0;
28 #else
29 static int MYDEBUG = 0;
30 #endif
31
32 namespace SMESH{
33   
34   using namespace std;
35
36   typedef map<string,HypothesisData*> THypothesisDataMap;
37   THypothesisDataMap myHypothesesMap;
38   THypothesisDataMap myAlgorithmsMap;
39
40   typedef map<string,SMESHGUI_GenericHypothesisCreator*> THypCreatorMap;
41   THypCreatorMap myHypCreatorMap;
42
43   void InitAvailableHypotheses()
44   {
45     QAD_WaitCursor wc;
46     if (myHypothesesMap.empty() && myAlgorithmsMap.empty()) {
47       // Resource manager
48       QAD_ResourceMgr* resMgr = QAD_Desktop::createResourceManager();
49       if (!resMgr) return;
50       
51       // Find name of a resource XML file ("SMESH_Meshers.xml");
52       QString HypsXml;
53       char* cenv = getenv("SMESH_MeshersList");
54       if (cenv)
55         HypsXml.sprintf("%s", cenv);
56       
57       QStringList HypsXmlList = QStringList::split( ":", HypsXml, false );
58       if (HypsXmlList.count() == 0)
59         {
60           QAD_MessageBox::error1(QAD_Application::getDesktop(),
61                                  tr("SMESH_WRN_WARNING"),
62                                  tr("MESHERS_FILE_NO_VARIABLE"),
63                                  tr("SMESH_BUT_OK"));
64           return;
65         }
66       
67       // loop on files in HypsXml
68       QString aNoAccessFiles;
69       for ( int i = 0; i < HypsXmlList.count(); i++ ) {
70         QString HypsXml = HypsXmlList[ i ];
71         
72         // Find full path to the resource XML file
73         QString xmlFile = HypsXml + ".xml";
74         xmlFile = QAD_Tools::addSlash(resMgr->findFile(xmlFile, HypsXml)) + xmlFile;
75         
76         QFile file (QAD_Tools::unix2win(xmlFile));
77         if (file.exists() && file.open(IO_ReadOnly)) {
78           file.close();
79           
80           SMESHGUI_XmlHandler* myXmlHandler = new SMESHGUI_XmlHandler();
81           ASSERT(myXmlHandler);
82           
83           QXmlInputSource source (file);
84           QXmlSimpleReader reader;
85           reader.setContentHandler(myXmlHandler);
86           reader.setErrorHandler(myXmlHandler);
87           bool ok = reader.parse(source);
88           file.close();
89           if (ok) {
90             addMap( myXmlHandler->myHypothesesMap, myHypothesesMap );
91             addMap( myXmlHandler->myAlgorithmsMap, myAlgorithmsMap );
92           }
93           else {
94             QAD_MessageBox::error1(myDesktop, 
95                                    tr("INF_PARSE_ERROR"),
96                                    tr(myXmlHandler->errorProtocol()),
97                                    tr("SMESH_BUT_OK"));
98           }
99         }
100         else {
101           if (aNoAccessFiles.isEmpty())
102             aNoAccessFiles = xmlFile;
103           else
104             aNoAccessFiles += ", " + xmlFile;
105         }
106       } // end loop
107       
108       
109       if (!aNoAccessFiles.isEmpty()) {
110         QString aMess = tr("MESHERS_FILE_CANT_OPEN") + " " + aNoAccessFiles + "\n";
111         aMess += tr("MESHERS_FILE_CHECK_VARIABLE");
112         wc.stop();
113         QAD_MessageBox::warn1(QAD_Application::getDesktop(),
114                               tr("SMESH_WRN_WARNING"),
115                               aMess,
116                               tr("SMESH_BUT_OK"));
117         wc.start();
118       }
119     }
120   }
121
122
123   GetAvailableHypotheses (const bool isAlgo)
124   {
125     QStringList aHypList;
126     
127     // Init list of available hypotheses, if needed
128     InitAvailableHypotheses();
129     
130     // fill list of hypotheses/algorithms
131     THypothesisDataMap::iterator anIter;
132     if (isAlgo) {
133       anIter = myAlgorithmsMap.begin();
134       for (; anIter != myAlgorithmsMap.end(); anIter++) {
135         aHypList.append(((*anIter).first).c_str());
136       }
137     }
138     else {
139       anIter = myHypothesesMap.begin();
140       for (; anIter != myHypothesesMap.end(); anIter++) {
141         aHypList.append(((*anIter).first).c_str());
142       }
143     }
144     
145     return aHypList;
146   }
147   
148
149   HypothesisData* GetHypothesisData (const char* aHypType)
150   {
151     HypothesisData* aHypData = 0;
152
153     // Init list of available hypotheses, if needed
154     InitAvailableHypotheses();
155
156     if (myHypothesesMap.find(aHypType) == myHypothesesMap.end()) {
157       if (myAlgorithmsMap.find(aHypType) != myAlgorithmsMap.end()) {
158         aHypData = myAlgorithmsMap[aHypType];
159       }
160     }
161     else {
162       aHypData = myHypothesesMap[aHypType];
163     }
164     return aHypData;
165   }
166
167
168   SMESHGUI_GenericHypothesisCreator* GetHypothesisCreator (const QString& aHypType)
169   {
170     const char* sHypType = aHypType.latin1();
171     if(MYDEBUG) MESSAGE("Get HypothesisCreator for " << sHypType);
172
173     SMESHGUI_GenericHypothesisCreator* aCreator = 0;
174     
175     // check, if creator for this hypothesis type already exists
176     if (myHypCreatorMap.find(sHypType) != myHypCreatorMap.end()) {
177       aCreator = myHypCreatorMap[sHypType];
178     }
179     else {
180       // 1. Init list of available hypotheses, if needed
181       InitAvailableHypotheses();
182
183       // 2. Get names of plugin libraries
184       HypothesisData* aHypData = GetHypothesisData(sHypType);
185       if (!aHypData) {
186         return aCreator;
187       }
188       QString aClientLibName = aHypData->ClientLibName;
189       QString aServerLibName = aHypData->ServerLibName;
190
191       // 3. Load Client Plugin Library
192       try {
193         // load plugin library
194         if(MYDEBUG) MESSAGE("Loading client meshers plugin library ...");
195         void* libHandle = dlopen (aClientLibName, RTLD_LAZY);
196         if (!libHandle) {
197           // report any error, if occured
198           const char* anError = dlerror();
199           if(MYDEBUG) MESSAGE(anError);
200         }
201         else {
202           // get method, returning hypothesis creator
203           if(MYDEBUG) MESSAGE("Find GetHypothesisCreator() method ...");
204           typedef SMESHGUI_GenericHypothesisCreator* (*GetHypothesisCreator) \
205             (QString aHypType, QString aServerLibName, SMESHGUI* aSMESHGUI);
206           GetHypothesisCreator procHandle =
207             (GetHypothesisCreator)dlsym( libHandle, "GetHypothesisCreator" );
208           if (!procHandle) {
209             if(MYDEBUG) MESSAGE("bad hypothesis client plugin library");
210             dlclose(libHandle);
211           }
212           else {
213             // get hypothesis creator
214             if(MYDEBUG) MESSAGE("Get Hypothesis Creator for " << aHypType);
215             aCreator = procHandle(aHypType, aServerLibName, smeshGUI);
216             if (!aCreator) {
217               if(MYDEBUG) MESSAGE("no such a hypothesis in this plugin");
218             }
219             else {
220               // map hypothesis creator to a hypothesis name
221               myHypCreatorMap[sHypType] = aCreator;
222             }
223           }
224         }
225       }
226       catch (const SALOME::SALOME_Exception& S_ex) {
227         QtCatchCorbaException(S_ex);
228       }
229     }
230
231     return aCreator;
232   }
233
234
235   SMESH::SMESH_Hypothesis_ptr CreateHypothesis (const QString& aHypType,
236                                                 const QString& aHypName,
237                                                 const bool     isAlgo = false)
238   {
239     if(MYDEBUG) MESSAGE("Create " << aHypType << " with name " << aHypName);
240
241     SMESH::SMESH_Hypothesis_var Hyp;
242     
243     HypothesisData* aHypData = GetHypothesisData((char*)aHypType.latin1());
244     QString aServLib = aHypData->ServerLibName;
245     
246     try {
247       Hyp = SMESH::GetSMESHGen()->CreateHypothesis(aHypType, aServLib);
248       if (!Hyp->_is_nil()) {
249         SALOMEDS::SObject_var SHyp = SMESH::FindSObject(Hyp.in());
250         if (!SHyp->_is_nil()) {
251           if ( !aHypName.isEmpty() )
252             SMESH::SetName( SHyp, aHypName );
253           myActiveStudy->updateObjBrowser(true);
254           return Hyp._retn();
255         }
256       }
257     }
258     catch (const SALOME::SALOME_Exception & S_ex) {
259       QtCatchCorbaException(S_ex);
260     }
261
262     return SMESH::SMESH_Hypothesis::_nil();
263   }
264
265
266   bool AddHypothesisOnMesh (SMESH::SMESH_Mesh_ptr aMesh, SMESH::SMESH_Hypothesis_ptr aHyp)
267   {
268     if(MYDEBUG) MESSAGE ("SMESHGUI::AddHypothesisOnMesh");
269     int res = SMESH::HYP_UNKNOWN_FATAL; 
270     QAD_WaitCursor wc;
271     
272     if ( !aMesh->_is_nil() ) {
273       SALOMEDS::SObject_var SM = SMESH::FindSObject( aMesh );
274       GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(SM);
275       try {
276         res = aMesh->AddHypothesis( aShapeObject, aHyp );
277         if ( res < SMESH::HYP_UNKNOWN_FATAL ) {
278           SALOMEDS::SObject_var SH = SMESH::FindSObject(aHyp);
279           if ( !SM->_is_nil() && !SH->_is_nil() ) {
280             SMESH::ModifiedMesh(SM, false);
281           }
282         }
283         if ( res > SMESH::HYP_OK ) {
284           wc.stop();
285           processHypothesisStatus( res, aHyp, this, true );
286           wc.start();
287         }
288       }
289       catch( const SALOME::SALOME_Exception& S_ex ) {
290         wc.stop();
291         QtCatchCorbaException( S_ex );
292         res = SMESH::HYP_UNKNOWN_FATAL;
293       }
294     }
295     return res < SMESH::HYP_UNKNOWN_FATAL;
296   }
297
298
299   bool AddHypothesisOnSubMesh (SMESH::SMESH_subMesh_ptr aSubMesh, SMESH::SMESH_Hypothesis_ptr aHyp)
300   {
301     if(MYDEBUG) MESSAGE( "SMESHGUI::AddHypothesisOnSubMesh() ");
302     int res = SMESH::HYP_UNKNOWN_FATAL;
303     QAD_WaitCursor wc;
304     
305     if ( !aSubMesh->_is_nil() && ! aHyp->_is_nil() ) {
306       try {
307         SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
308         SALOMEDS::SObject_var SsubM = SMESH::FindSObject( aSubMesh );
309         GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh( SsubM );
310         if ( !aMesh->_is_nil() && !SsubM->_is_nil() && !aShapeObject->_is_nil() ) {
311           res = aMesh->AddHypothesis( aShapeObject, aHyp );
312           if ( res < SMESH::HYP_UNKNOWN_FATAL )  {
313             SMESH::ModifiedMesh( SsubM, false );
314           }
315           if ( res > SMESH::HYP_OK ) {
316             wc.stop();
317             processHypothesisStatus( res, aHyp, this, true );
318             wc.start();
319           }
320         }
321         else {
322           SCRUTE( aHyp->_is_nil() );
323           SCRUTE( aMesh->_is_nil() );
324           SCRUTE( SsubM->_is_nil() );
325           SCRUTE( aShapeObject->_is_nil() );
326         }
327       }
328       catch( const SALOME::SALOME_Exception& S_ex ) {
329         wc.stop();
330         QtCatchCorbaException( S_ex );
331         res = SMESH::HYP_UNKNOWN_FATAL;
332       }
333     }
334     else {
335       SCRUTE( aSubMesh->_is_nil() );
336       SCRUTE( aHyp->_is_nil() );
337     }
338     return res < SMESH::HYP_UNKNOWN_FATAL;
339   }
340   
341   bool RemoveHypothesisOrAlgorithmOnMesh (const Handle(SALOME_InteractiveObject)& IObject)
342   {
343     int res = SMESH::HYP_UNKNOWN_FATAL;
344     QAD_WaitCursor wc;
345     
346     if (IObject->hasReference()) {
347       try {
348         SMESH::SMESH_Hypothesis_var anHyp = 
349           SMESH::IObjectToInterface<SMESH::SMESH_Hypothesis>(IObject);
350         SALOMEDS::SObject_var SO_Applied_Hypothesis =
351           smeshGUI->myStudy->FindObjectID(IObject->getReference());
352         if (!SO_Applied_Hypothesis->_is_nil()) {
353           SALOMEDS::SObject_var MorSM = SMESH::GetMeshOrSubmesh(SO_Applied_Hypothesis);
354           if (!MorSM->_is_nil()) {
355             GEOM::GEOM_Object_var aShape = SMESH::GetShapeOnMeshOrSubMesh(MorSM);
356             if (!aShape->_is_nil()){
357               SMESH::SMESH_Mesh_var aMesh = 
358                 SMESH::SObjectToInterface<SMESH::SMESH_Mesh>(MorSM);
359               SMESH::SMESH_subMesh_var aSubMesh =
360                 SMESH::SObjectToInterface<SMESH::SMESH_subMesh>(MorSM);
361               
362               if (!aSubMesh->_is_nil())
363                 aMesh = aSubMesh->GetFather();
364               
365               if (!aMesh->_is_nil()) {
366                 res = aMesh->RemoveHypothesis(aShape, anHyp);
367                 if ( res < SMESH::HYP_UNKNOWN_FATAL )
368                   SMESH::ModifiedMesh(MorSM, false);
369                 if ( res > SMESH::HYP_OK ) {
370                   wc.stop();
371                   processHypothesisStatus( res, anHyp, this, false );
372                   wc.start();
373                 }
374               }
375             }
376           }
377           
378           SALOMEDS::SObject_var SO_Applied_Hypothesis =
379             smeshGUI->myStudy->FindObjectID(IObject->getReference());
380           if (!SO_Applied_Hypothesis->_is_nil()) {
381             SALOMEDS::SObject_var MorSM = SMESH::GetMeshOrSubmesh(SO_Applied_Hypothesis);
382             if (!MorSM->_is_nil()) {
383               GEOM::GEOM_Object_var aShapeObject =SMESH::GetShapeOnMeshOrSubMesh(MorSM);
384               if (!aShapeObject->_is_nil()){
385                 SMESH::SMESH_Mesh_var aMesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>(MorSM);
386                 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SObjectToInterface<SMESH::SMESH_subMesh>(MorSM);
387                 
388                 if (!aSubMesh->_is_nil())
389                   aMesh = aSubMesh->GetFather();
390                 
391                 if (!aMesh->_is_nil()) {
392                   res = aMesh->RemoveHypothesis(aShapeObject, anHyp);
393                   if ( res < SMESH::HYP_UNKNOWN_FATAL )
394                     SMESH::ModifiedMesh(MorSM, false);
395                   if ( res > SMESH::HYP_OK ) {
396                     wc.stop();
397                     processHypothesisStatus( res, anHyp, this, false );
398                     wc.start();
399                   }
400                 }
401               }
402             }
403           }
404         }
405       }
406       catch( const SALOME::SALOME_Exception& S_ex ) {
407         wc.stop();
408         QtCatchCorbaException( S_ex );
409         res = SMESH::HYP_UNKNOWN_FATAL;
410       }
411     } 
412     else if (IObject->hasEntry()) {
413       if(MYDEBUG) MESSAGE("IObject entry " << IObject->getEntry());
414     }
415     return res < SMESH::HYP_UNKNOWN_FATAL;
416   }
417   
418   bool RemoveHypothesisOrAlgorithmOnMesh (SALOMEDS::SObject_ptr MorSM,
419                                           SMESH::SMESH_Hypothesis_ptr anHyp)
420   {
421     SALOMEDS::SObject_var AHR, aRef;
422     SALOMEDS::GenericAttribute_var anAttr;
423     SALOMEDS::AttributeIOR_var anIOR;
424     int res = SMESH::HYP_UNKNOWN_FATAL;
425     QAD_WaitCursor wc;
426     
427     if (!MorSM->_is_nil()) {
428       try {
429         GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(MorSM);
430         if (!aShapeObject->_is_nil()) {
431           SMESH::SMESH_Mesh_var aMesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>(MorSM);
432           SMESH::SMESH_subMesh_var aSubMesh = SMESH::SObjectToInterface<SMESH::SMESH_subMesh>(MorSM);
433           
434           if ( !aSubMesh->_is_nil() )
435             aMesh = aSubMesh->GetFather();
436           
437           if (!aMesh->_is_nil()) {
438             res = aMesh->RemoveHypothesis(aShapeObject, anHyp);
439             if ( res < SMESH::HYP_UNKNOWN_FATAL )
440               SMESH::ModifiedMesh(MorSM, false);
441             if ( res > SMESH::HYP_OK ) {
442               wc.stop();
443               processHypothesisStatus( res, anHyp, this, false );
444               wc.start();
445             }
446           }
447         }
448       } catch( const SALOME::SALOME_Exception& S_ex ) {
449         wc.stop();
450         QtCatchCorbaException( S_ex );
451         res = SMESH::HYP_UNKNOWN_FATAL;
452       }
453     }
454     return res < SMESH::HYP_UNKNOWN_FATAL;
455   }
456
457   SALOMEDS::Study::ListOfSObject* GetMeshesUsingAlgoOrHypothesis( SMESH::SMESH_Hypothesis_ptr AlgoOrHyp )
458   {
459     SALOMEDS::Study::ListOfSObject_var listSOmesh =
460       new SALOMEDS::Study::ListOfSObject;
461     listSOmesh->length(0);
462     unsigned int index = 0;
463     if (!AlgoOrHyp->_is_nil()) {
464       SALOMEDS::SObject_var SO_Hypothesis = SMESH::FindSObject(AlgoOrHyp);
465       if (!SO_Hypothesis->_is_nil()) {
466         SALOMEDS::Study::ListOfSObject_var listSO =
467           smeshGUI->myStudy->FindDependances(SO_Hypothesis);
468         if(MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency number ="<<listSO->length());
469         for (unsigned int i = 0; i < listSO->length(); i++) {
470           SALOMEDS::SObject_ptr SO = listSO[i];
471           if (!SO->_is_nil()) { 
472             SALOMEDS::SObject_var aFather = SO->GetFather();
473             if (!aFather->_is_nil()) {
474               SALOMEDS::SObject_var SOfatherFather = aFather->GetFather();
475               if (!SOfatherFather->_is_nil()) {
476                 if(MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency added to list");
477                 index++;
478                 listSOmesh->length(index);
479                 listSOmesh[index - 1] = SOfatherFather;
480               }
481             }
482           }
483         }
484       }
485     }
486     if(MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): completed");
487     return listSOmesh._retn();
488   }
489
490 }