Salome HOME
0b9b9ea9dd5a8b4520f7551940c74ac894d69c25
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_HypothesesUtils.cxx
1 // SMESH SMESHGUI : GUI for SMESH component
2 //
3 // Copyright (C) 2003  CEA
4 //
5 // This library is free software; you can redistribute it and/or 
6 // modify it under the terms of the GNU Lesser General Public 
7 // License as published by the Free Software Foundation; either 
8 // version 2.1 of the License. 
9 //
10 // This library is distributed in the hope that it will be useful, 
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
13 // Lesser General Public License for more details. 
14 //
15 // You should have received a copy of the GNU Lesser General Public 
16 // License along with this library; if not, write to the Free Software 
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
18 //
19 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 //
21 // File   : SMESHGUI_HypothesesUtils.cxx
22 // Author : Julia DOROVSKIKH, Open CASCADE S.A.S.
23 //
24
25 // SMESH includes
26 #include "SMESHGUI_HypothesesUtils.h"
27
28 #include "SMESHGUI.h"
29 #include "SMESHGUI_Hypotheses.h"
30 #include "SMESHGUI_XmlHandler.h"
31 #include "SMESHGUI_Utils.h"
32 #include "SMESHGUI_GEOMGenUtils.h"
33
34 // SALOME GUI includes
35 #include <SUIT_Desktop.h>
36 #include <SUIT_MessageBox.h>
37 #include <SUIT_OverrideCursor.h>
38 #include <SUIT_ResourceMgr.h>
39
40 #include <SalomeApp_Study.h>
41 #include <SalomeApp_Tools.h>
42
43 // SALOME KERNEL includes
44 #include <utilities.h>
45
46 // STL includes
47 #include <string>
48
49 // Qt includes
50 #include <QMap>
51 //#include <QList>
52
53 // Other includes
54 #ifdef WNT
55 #include <windows.h>
56 #else
57 #include <dlfcn.h>
58 #endif
59
60 #ifdef WNT
61 #define LibHandle HMODULE
62 #define LoadLib( name ) LoadLibrary( name )
63 #define GetProc GetProcAddress
64 #define UnLoadLib( handle ) FreeLibrary( handle );
65 #else
66 #define LibHandle void*
67 #define LoadLib( name ) dlopen( name, RTLD_LAZY )
68 #define GetProc dlsym
69 #define UnLoadLib( handle ) dlclose( handle );
70 #endif
71
72 #ifdef _DEBUG_
73 static int MYDEBUG = 0;
74 #else
75 static int MYDEBUG = 0;
76 #endif
77
78 namespace SMESH
79 {
80   typedef QMap<QString,HypothesisData*> THypothesisDataMap;
81   THypothesisDataMap myHypothesesMap;
82   THypothesisDataMap myAlgorithmsMap;
83
84   typedef QMap<QString,SMESHGUI_GenericHypothesisCreator*> THypCreatorMap;
85   THypCreatorMap myHypCreatorMap;
86
87   QList<HypothesesSet*> myListOfHypothesesSets;
88
89   void processHypothesisStatus(const int theHypStatus,
90                                SMESH::SMESH_Hypothesis_ptr theHyp,
91                                const bool theIsAddition)
92   {
93     if (theHypStatus > SMESH::HYP_OK) {
94       // get Hyp name
95       QString aHypName ("NULL Hypothesis");
96       if (!CORBA::is_nil(theHyp)) {
97         _PTR(SObject) Shyp = SMESH::FindSObject(theHyp);
98         if (Shyp)
99           // name in study
100           aHypName = Shyp->GetName().c_str();
101         else
102           // label in xml file
103           aHypName = GetHypothesisData(theHyp->GetName())->Label;
104       }
105
106       // message
107       bool isFatal = (theHypStatus >= SMESH::HYP_UNKNOWN_FATAL);
108       QString aMsg;
109       if (theIsAddition)
110         aMsg = (isFatal ? "SMESH_CANT_ADD_HYP" : "SMESH_ADD_HYP_WRN");
111       else
112         aMsg = (isFatal ? "SMESH_CANT_RM_HYP"  : "SMESH_RM_HYP_WRN");
113
114       aMsg = QObject::tr(aMsg.toLatin1().data()).arg(aHypName) +
115         QObject::tr(QString("SMESH_HYP_%1").arg(theHypStatus).toLatin1().data());
116
117       if ( theHypStatus == SMESH::HYP_HIDDEN_ALGO ) // PAL18501
118         aMsg = aMsg.arg( GetHypothesisData(theHyp->GetName())->Dim[0] );
119
120       SUIT_MessageBox::warning(SMESHGUI::desktop(),
121                                QObject::tr("SMESH_WRN_WARNING"),
122                                aMsg);
123     }
124   }
125
126
127   void InitAvailableHypotheses()
128   {
129     SUIT_OverrideCursor wc;
130     if (myHypothesesMap.empty() && myAlgorithmsMap.empty()) {
131       // Resource manager
132       SUIT_ResourceMgr* resMgr = SMESHGUI::resourceMgr();
133       if (!resMgr) return;
134
135       // Find name of a resource XML file ("SMESH_Meshers.xml");
136       QString HypsXml;
137       char* cenv = getenv("SMESH_MeshersList");
138       if (cenv)
139         HypsXml.sprintf("%s", cenv);
140
141       QStringList HypsXmlList = HypsXml.split(":", QString::SkipEmptyParts);
142       if (HypsXmlList.count() == 0) {
143         SUIT_MessageBox::critical(SMESHGUI::desktop(),
144                                   QObject::tr("SMESH_WRN_WARNING"),
145                                   QObject::tr("MESHERS_FILE_NO_VARIABLE"));
146         return;
147       }
148
149       // loop on files in HypsXml
150       QString aNoAccessFiles;
151       for (int i = 0; i < HypsXmlList.count(); i++) {
152         QString HypsXml = HypsXmlList[ i ];
153
154         // Find full path to the resource XML file
155         QString xmlFile = resMgr->path("resources", "SMESH", HypsXml + ".xml");
156         if ( xmlFile.isEmpty() ) // try PLUGIN resources
157           xmlFile = resMgr->path("resources", HypsXml, HypsXml + ".xml");
158         
159         QFile file (xmlFile);
160         if (file.exists() && file.open(QIODevice::ReadOnly)) {
161           file.close();
162
163           SMESHGUI_XmlHandler* aXmlHandler = new SMESHGUI_XmlHandler();
164           ASSERT(aXmlHandler);
165
166           QXmlInputSource source (&file);
167           QXmlSimpleReader reader;
168           reader.setContentHandler(aXmlHandler);
169           reader.setErrorHandler(aXmlHandler);
170           bool ok = reader.parse(source);
171           file.close();
172           if (ok) {
173             myHypothesesMap.unite( aXmlHandler->myHypothesesMap );
174             myAlgorithmsMap.unite( aXmlHandler->myAlgorithmsMap );
175             QList<HypothesesSet*>::iterator it, pos = myListOfHypothesesSets.begin();
176             for ( it = aXmlHandler->myListOfHypothesesSets.begin(); 
177                   it != aXmlHandler->myListOfHypothesesSets.end();
178                   ++it ) {
179               myListOfHypothesesSets.insert( pos, *it );
180             }
181           }
182           else {
183             SUIT_MessageBox::critical(SMESHGUI::desktop(),
184                                       QObject::tr("INF_PARSE_ERROR"),
185                                       QObject::tr(aXmlHandler->errorProtocol().toLatin1().data()));
186           }
187         }
188         else {
189           if (aNoAccessFiles.isEmpty())
190             aNoAccessFiles = xmlFile;
191           else
192             aNoAccessFiles += ", " + xmlFile;
193         }
194       } // end loop
195
196
197       if (!aNoAccessFiles.isEmpty()) {
198         QString aMess = QObject::tr("MESHERS_FILE_CANT_OPEN") + " " + aNoAccessFiles + "\n";
199         aMess += QObject::tr("MESHERS_FILE_CHECK_VARIABLE");
200         wc.suspend();
201         SUIT_MessageBox::warning(SMESHGUI::desktop(),
202                                  QObject::tr("SMESH_WRN_WARNING"),
203                                  aMess);
204         wc.resume();
205       }
206     }
207   }
208
209
210   QStringList GetAvailableHypotheses( const bool isAlgo, 
211                                       const int theDim,                          
212                                       const bool isAux,
213                                       const bool isNeedGeometry)
214   {
215     QStringList aHypList;
216
217     // Init list of available hypotheses, if needed
218     InitAvailableHypotheses();
219     bool checkGeometry = ( !isNeedGeometry && isAlgo );
220     // fill list of hypotheses/algorithms
221     THypothesisDataMap& pMap = isAlgo ? myAlgorithmsMap : myHypothesesMap;
222     THypothesisDataMap::iterator anIter;
223     for ( anIter = pMap.begin(); anIter != pMap.end(); anIter++ ) {
224       HypothesisData* aData = anIter.value();
225       if ( ( theDim < 0 || aData->Dim.contains( theDim ) ) && aData->IsAux == isAux) {
226         if (checkGeometry) {
227           if (aData->IsNeedGeometry == isNeedGeometry)
228             aHypList.append(anIter.key());
229         }
230         else {
231           aHypList.append(anIter.key());
232         }
233       }
234     }
235     return aHypList;
236   }
237
238
239   QStringList GetHypothesesSets()
240   {
241     QStringList aSetNameList;
242
243     // Init list of available hypotheses, if needed
244     InitAvailableHypotheses();
245
246     QList<HypothesesSet*>::iterator hypoSet;
247     for ( hypoSet  = myListOfHypothesesSets.begin(); 
248           hypoSet != myListOfHypothesesSets.end();
249           ++hypoSet ) {
250       HypothesesSet* aSet = *hypoSet;
251       if ( aSet && aSet->AlgoList.count() ) {
252         aSetNameList.append( aSet->HypoSetName );
253       }
254     }
255     
256     return aSetNameList;
257   }
258
259   HypothesesSet* GetHypothesesSet(const QString& theSetName)
260   {
261     QList<HypothesesSet*>::iterator hypoSet;
262     for ( hypoSet  = myListOfHypothesesSets.begin(); 
263           hypoSet != myListOfHypothesesSets.end();
264           ++hypoSet ) {
265       HypothesesSet* aSet = *hypoSet;
266       if ( aSet && aSet->HypoSetName == theSetName )
267         return aSet;
268     }
269     return 0;
270   }
271
272   HypothesisData* GetHypothesisData (const QString& aHypType)
273   {
274     HypothesisData* aHypData = 0;
275
276     // Init list of available hypotheses, if needed
277     InitAvailableHypotheses();
278
279     if (myHypothesesMap.find(aHypType) != myHypothesesMap.end()) {
280       aHypData = myHypothesesMap[aHypType];
281     }
282     else if (myAlgorithmsMap.find(aHypType) != myAlgorithmsMap.end()) {
283       aHypData = myAlgorithmsMap[aHypType];
284     }
285     return aHypData;
286   }
287
288   bool IsAvailableHypothesis(const HypothesisData* algoData,
289                              const QString&        hypType,
290                              bool&                 isAuxiliary)
291   {
292     isAuxiliary = false;
293     if ( !algoData )
294       return false;
295     if ( algoData->NeededHypos.contains( hypType ))
296       return true;
297     if ( algoData->OptionalHypos.contains( hypType)) {
298       isAuxiliary = true;
299       return true;
300     }
301     return false;
302   }
303
304   bool IsCompatibleAlgorithm(const HypothesisData* algo1Data,
305                              const HypothesisData* algo2Data)
306   {
307     if ( !algo1Data || !algo2Data )
308       return false;
309     const HypothesisData* algoIn = algo1Data, *algoMain = algo2Data;
310     if ( algoIn->Dim.first() > algoMain->Dim.first() ) {
311       algoIn = algo2Data; algoMain = algo1Data;
312     }
313     // look for any output type of algoIn between input types of algoMain
314     QStringList::const_iterator inElemType = algoIn->OutputTypes.begin();
315     for ( ; inElemType != algoIn->OutputTypes.end(); ++inElemType )
316       if ( algoMain->InputTypes.contains( *inElemType ))
317         return true;
318     return false;
319   }
320
321   SMESHGUI_GenericHypothesisCreator* GetHypothesisCreator(const QString& aHypType)
322   {
323     if(MYDEBUG) MESSAGE("Get HypothesisCreator for " << aHypType.toLatin1().data());
324
325     SMESHGUI_GenericHypothesisCreator* aCreator = 0;
326
327     // check, if creator for this hypothesis type already exists
328     if (myHypCreatorMap.find(aHypType) != myHypCreatorMap.end()) {
329       aCreator = myHypCreatorMap[aHypType];
330     }
331     else {
332       // 1. Init list of available hypotheses, if needed
333       InitAvailableHypotheses();
334
335       // 2. Get names of plugin libraries
336       HypothesisData* aHypData = GetHypothesisData(aHypType);
337       if (!aHypData) 
338         return aCreator;
339       QString aClientLibName = aHypData->ClientLibName;
340       QString aServerLibName = aHypData->ServerLibName;
341
342       // 3. Load Client Plugin Library
343       try {
344         // load plugin library
345         if(MYDEBUG) MESSAGE("Loading client meshers plugin library ...");
346         LibHandle libHandle = LoadLib( aClientLibName.toLatin1().data() );
347         if (!libHandle) {
348           // report any error, if occured
349           if ( MYDEBUG ) {
350 #ifdef WIN32
351             const char* anError = "Can't load client meshers plugin library";
352 #else
353             const char* anError = dlerror();      
354 #endif
355             MESSAGE(anError);
356           }
357         }
358         else {
359           // get method, returning hypothesis creator
360           if(MYDEBUG) MESSAGE("Find GetHypothesisCreator() method ...");
361           typedef SMESHGUI_GenericHypothesisCreator* (*GetHypothesisCreator) \
362             ( const QString& );
363           GetHypothesisCreator procHandle =
364             (GetHypothesisCreator)GetProc(libHandle, "GetHypothesisCreator");
365           if (!procHandle) {
366             if(MYDEBUG) MESSAGE("bad hypothesis client plugin library");
367             UnLoadLib(libHandle);
368           }
369           else {
370             // get hypothesis creator
371             if(MYDEBUG) MESSAGE("Get Hypothesis Creator for " << aHypType.toLatin1().data());
372             aCreator = procHandle( aHypType );
373             if (!aCreator) {
374               if(MYDEBUG) MESSAGE("no such a hypothesis in this plugin");
375             }
376             else {
377               // map hypothesis creator to a hypothesis name
378               myHypCreatorMap[aHypType] = aCreator;
379             }
380           }
381         }
382       }
383       catch (const SALOME::SALOME_Exception& S_ex) {
384         SalomeApp_Tools::QtCatchCorbaException(S_ex);
385       }
386     }
387
388     return aCreator;
389   }
390
391
392   SMESH::SMESH_Hypothesis_ptr CreateHypothesis(const QString& aHypType,
393                                                const QString& aHypName,
394                                                const bool isAlgo)
395   {
396     if(MYDEBUG) MESSAGE("Create " << aHypType.toLatin1().data() << 
397                         " with name " << aHypName.toLatin1().data());
398     HypothesisData* aHypData = GetHypothesisData(aHypType);
399     QString aServLib = aHypData->ServerLibName;
400     try {
401       SMESH::SMESH_Hypothesis_var aHypothesis;
402       aHypothesis = SMESHGUI::GetSMESHGen()->CreateHypothesis(aHypType.toLatin1().data(),
403                                                               aServLib.toLatin1().data());
404       if (!aHypothesis->_is_nil()) {
405         _PTR(SObject) aHypSObject = SMESH::FindSObject(aHypothesis.in());
406         if (aHypSObject) {
407           if (!aHypName.isEmpty())
408             SMESH::SetName(aHypSObject, aHypName);
409           SMESHGUI::GetSMESHGUI()->updateObjBrowser();
410           return aHypothesis._retn();
411         }
412       }
413     } catch (const SALOME::SALOME_Exception & S_ex) {
414       SalomeApp_Tools::QtCatchCorbaException(S_ex);
415     }
416
417     return SMESH::SMESH_Hypothesis::_nil();
418   }
419
420
421   bool AddHypothesisOnMesh (SMESH::SMESH_Mesh_ptr aMesh, SMESH::SMESH_Hypothesis_ptr aHyp)
422   {
423     if(MYDEBUG) MESSAGE ("SMESHGUI::AddHypothesisOnMesh");
424     int res = SMESH::HYP_UNKNOWN_FATAL;
425     SUIT_OverrideCursor wc;
426
427     if (!aMesh->_is_nil()) {
428       _PTR(SObject) SM = SMESH::FindSObject(aMesh);
429       GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(SM);
430       try {
431         res = aMesh->AddHypothesis(aShapeObject, aHyp);
432         if (res < SMESH::HYP_UNKNOWN_FATAL) {
433           _PTR(SObject) aSH = SMESH::FindSObject(aHyp);
434           if (SM && aSH) {
435             SMESH::ModifiedMesh(SM, false, aMesh->NbNodes()==0);
436           }
437         }
438         if (res > SMESH::HYP_OK) {
439           wc.suspend();
440           processHypothesisStatus(res, aHyp, true);
441           wc.resume();
442         }
443       }
444       catch(const SALOME::SALOME_Exception& S_ex) {
445         wc.suspend();
446         SalomeApp_Tools::QtCatchCorbaException(S_ex);
447         res = SMESH::HYP_UNKNOWN_FATAL;
448       }
449     }
450     return res < SMESH::HYP_UNKNOWN_FATAL;
451   }
452
453
454   bool AddHypothesisOnSubMesh (SMESH::SMESH_subMesh_ptr aSubMesh, SMESH::SMESH_Hypothesis_ptr aHyp)
455   {
456     if(MYDEBUG) MESSAGE("SMESHGUI::AddHypothesisOnSubMesh() ");
457     int res = SMESH::HYP_UNKNOWN_FATAL;
458     SUIT_OverrideCursor wc;
459
460     if (!aSubMesh->_is_nil() && ! aHyp->_is_nil()) {
461       try {
462         SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
463         _PTR(SObject) SsubM = SMESH::FindSObject(aSubMesh);
464         GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(SsubM);
465         if (!aMesh->_is_nil() && SsubM && !aShapeObject->_is_nil()) {
466           res = aMesh->AddHypothesis(aShapeObject, aHyp);
467           if (res < SMESH::HYP_UNKNOWN_FATAL)  {
468             _PTR(SObject) meshSO = SMESH::FindSObject(aMesh);
469             if (meshSO)
470               SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0);
471           }
472           if (res > SMESH::HYP_OK) {
473             wc.suspend();
474             processHypothesisStatus(res, aHyp, true);
475             wc.resume();
476           }
477         }
478         else {
479           SCRUTE(aHyp->_is_nil());
480           SCRUTE(aMesh->_is_nil());
481           SCRUTE(!SsubM);
482           SCRUTE(aShapeObject->_is_nil());
483         }
484       }
485       catch(const SALOME::SALOME_Exception& S_ex) {
486         wc.suspend();
487         SalomeApp_Tools::QtCatchCorbaException(S_ex);
488         res = SMESH::HYP_UNKNOWN_FATAL;
489       }
490     }
491     else {
492       SCRUTE(aSubMesh->_is_nil());
493       SCRUTE(aHyp->_is_nil());
494     }
495     return res < SMESH::HYP_UNKNOWN_FATAL;
496   }
497
498   bool RemoveHypothesisOrAlgorithmOnMesh (const Handle(SALOME_InteractiveObject)& IObject)
499   {
500     int res = SMESH::HYP_UNKNOWN_FATAL;
501     SUIT_OverrideCursor wc;
502
503     try {
504       _PTR(Study) aStudy = GetActiveStudyDocument();
505       _PTR(SObject) aHypObj = aStudy->FindObjectID( IObject->getEntry() );
506       if( aHypObj )
507         {
508           _PTR(SObject) MorSM = SMESH::GetMeshOrSubmesh( aHypObj );
509           _PTR(SObject) aRealHypo;
510           if( aHypObj->ReferencedObject( aRealHypo ) )
511             {
512               SMESH_Hypothesis_var hypo = SMESH_Hypothesis::_narrow( SObjectToObject( aRealHypo ) );
513               RemoveHypothesisOrAlgorithmOnMesh( MorSM, hypo );
514             }
515           else
516             {
517               SMESH_Hypothesis_var hypo = SMESH_Hypothesis::_narrow( SObjectToObject( aHypObj ) );
518               SObjectList meshList = GetMeshesUsingAlgoOrHypothesis( hypo );
519               for( int i = 0; i < meshList.size(); i++ )
520                 RemoveHypothesisOrAlgorithmOnMesh( meshList[ i ], hypo );
521             }
522         }
523     }
524     catch(const SALOME::SALOME_Exception& S_ex)
525       {
526         wc.suspend();
527         SalomeApp_Tools::QtCatchCorbaException(S_ex);
528         res = SMESH::HYP_UNKNOWN_FATAL;
529       }
530     return res < SMESH::HYP_UNKNOWN_FATAL;
531   }
532
533   bool RemoveHypothesisOrAlgorithmOnMesh (_PTR(SObject) MorSM,
534                                           SMESH::SMESH_Hypothesis_ptr anHyp)
535   {
536     SALOMEDS::GenericAttribute_var anAttr;
537     SALOMEDS::AttributeIOR_var anIOR;
538     int res = SMESH::HYP_UNKNOWN_FATAL;
539     SUIT_OverrideCursor wc;
540
541     if (MorSM) {
542       try {
543         GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(MorSM);
544         SMESH::SMESH_Mesh_var aMesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>(MorSM);
545         SMESH::SMESH_subMesh_var aSubMesh = SMESH::SObjectToInterface<SMESH::SMESH_subMesh>(MorSM);
546         
547         if (!aSubMesh->_is_nil())
548           aMesh = aSubMesh->GetFather();
549         
550         if (!aMesh->_is_nil()) {    
551           if (aMesh->HasShapeToMesh() && !aShapeObject->_is_nil()) {
552             res = aMesh->RemoveHypothesis(aShapeObject, anHyp);
553             if (res < SMESH::HYP_UNKNOWN_FATAL) {
554               _PTR(SObject) meshSO = SMESH::FindSObject(aMesh);
555               if (meshSO)
556                 SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0);
557             }
558             
559           }
560           else if(!aMesh->HasShapeToMesh()){
561             res = aMesh->RemoveHypothesis(aShapeObject, anHyp);
562             if (res < SMESH::HYP_UNKNOWN_FATAL) {
563               _PTR(SObject) meshSO = SMESH::FindSObject(aMesh);
564               if (meshSO)
565                 SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0);              
566             }
567           }
568           if (res > SMESH::HYP_OK) {
569             wc.suspend();
570             processHypothesisStatus(res, anHyp, false);
571             wc.resume();
572           }
573         }
574       } catch(const SALOME::SALOME_Exception& S_ex) {
575         wc.suspend();
576         SalomeApp_Tools::QtCatchCorbaException(S_ex);
577         res = SMESH::HYP_UNKNOWN_FATAL;
578       }
579     }
580     return res < SMESH::HYP_UNKNOWN_FATAL;
581   }
582
583   SObjectList GetMeshesUsingAlgoOrHypothesis(SMESH::SMESH_Hypothesis_ptr AlgoOrHyp)
584   {
585     SObjectList listSOmesh;
586     listSOmesh.resize(0);
587
588     unsigned int index = 0;
589     if (!AlgoOrHyp->_is_nil()) {
590       _PTR(SObject) SO_Hypothesis = SMESH::FindSObject(AlgoOrHyp);
591       if (SO_Hypothesis) {
592         SObjectList listSO =
593           SMESHGUI::activeStudy()->studyDS()->FindDependances(SO_Hypothesis);
594
595         if(MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency number ="<<listSO.size());
596         for (unsigned int i = 0; i < listSO.size(); i++) {
597           _PTR(SObject) SO = listSO[i];
598           if (SO) {
599             _PTR(SObject) aFather = SO->GetFather();
600             if (aFather) {
601               _PTR(SObject) SOfatherFather = aFather->GetFather();
602               if (SOfatherFather) {
603                 if(MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency added to list");
604                 index++;
605                 listSOmesh.resize(index);
606                 listSOmesh[index - 1] = SOfatherFather;
607               }
608             }
609           }
610         }
611       }
612     }
613     if (MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): completed");
614     return listSOmesh;
615   }
616
617 #define CASE2MESSAGE(enum) case SMESH::enum: msg = QObject::tr( "STATE_" #enum ); break;
618   QString GetMessageOnAlgoStateErrors(const algo_error_array& errors)
619   {
620     QString resMsg; // PAL14861 = QObject::tr("SMESH_WRN_MISSING_PARAMETERS") + ":\n";
621     for ( int i = 0; i < errors.length(); ++i ) {
622       const SMESH::AlgoStateError & error = errors[ i ];
623       const bool hasAlgo = ( strlen( error.algoName ) != 0 );
624       QString msg;
625       if ( !hasAlgo )
626         msg = QObject::tr( "STATE_ALGO_MISSING" );
627       else 
628         switch( error.state ) {
629           CASE2MESSAGE( HYP_MISSING );
630           CASE2MESSAGE( HYP_NOTCONFORM );
631           CASE2MESSAGE( HYP_BAD_PARAMETER );
632           CASE2MESSAGE( HYP_BAD_GEOMETRY );
633         default: continue;
634         }
635       // apply args to message:
636       // %1 - algo name
637       if ( hasAlgo )
638         msg = msg.arg( error.algoName.in() );
639       // %2 - dimension
640       msg = msg.arg( error.algoDim );
641       // %3 - global/local
642       msg = msg.arg( QObject::tr( error.isGlobalAlgo ? "GLOBAL_ALGO" : "LOCAL_ALGO" ));
643       // %4 - hypothesis dim == algoDim
644       msg = msg.arg( error.algoDim );
645
646       if ( i ) resMsg += ";\n";
647       resMsg += msg;
648     }
649     return resMsg;
650   }
651 } // end of namespace SMESH