1 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
18 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
20 #include "SMESHGUI_HypothesesUtils.h"
23 #include "SMESHGUI_Hypotheses.h"
24 #include "SMESHGUI_XmlHandler.h"
25 #include "SMESHGUI_Utils.h"
26 #include "SMESHGUI_GEOMGenUtils.h"
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"
35 #include "OB_Browser.h"
37 #include "SalomeApp_Study.h"
38 #include "SalomeApp_Tools.h"
39 #include "SalomeApp_Application.h"
41 #include <SALOMEDSClient_Study.hxx>
42 #include <SALOMEDSClient_SObject.hxx>
44 #include "SALOMEconfig.h"
45 #include CORBA_CLIENT_HEADER(SALOMEDS_Attributes)
57 #define LibHandle HMODULE
58 #define LoadLib( name ) LoadLibrary( name )
59 #define GetProc GetProcAddress
60 #define UnLoadLib( handle ) FreeLibrary( handle );
62 #define LibHandle void*
63 #define LoadLib( name ) dlopen( name, RTLD_LAZY )
65 #define UnLoadLib( handle ) dlclose( handle );
69 static int MYDEBUG = 0;
71 static int MYDEBUG = 0;
78 typedef map<string,HypothesisData*> THypothesisDataMap;
79 THypothesisDataMap myHypothesesMap;
80 THypothesisDataMap myAlgorithmsMap;
82 typedef map<string,SMESHGUI_GenericHypothesisCreator*> THypCreatorMap;
83 THypCreatorMap myHypCreatorMap;
85 list<HypothesesSet*> myListOfHypothesesSets;
87 void processHypothesisStatus(const int theHypStatus,
88 SMESH::SMESH_Hypothesis_ptr theHyp,
89 const bool theIsAddition)
91 if (theHypStatus > SMESH::HYP_OK) {
94 QString aHypName ("NULL Hypothesis");
95 if (!CORBA::is_nil(theHyp)) {
96 _PTR(SObject) Shyp = SMESH::FindSObject(theHyp);
99 aHypName = Shyp->GetName().c_str();
102 aHypName = GetHypothesisData(theHyp->GetName())->Label;
106 bool isFatal = (theHypStatus >= SMESH::HYP_UNKNOWN_FATAL);
109 aMsg = (isFatal ? "SMESH_CANT_ADD_HYP" : "SMESH_ADD_HYP_WRN");
111 aMsg = (isFatal ? "SMESH_CANT_RM_HYP" : "SMESH_RM_HYP_WRN");
113 aMsg = QObject::tr(aMsg).arg(aHypName) +
114 QObject::tr(QString("SMESH_HYP_%1").arg(theHypStatus));
116 SUIT_MessageBox::warn1(SMESHGUI::desktop(),
117 QObject::tr("SMESH_WRN_WARNING"),
119 QObject::tr("SMESH_BUT_OK"));
124 void InitAvailableHypotheses()
126 SUIT_OverrideCursor wc;
127 if (myHypothesesMap.empty() && myAlgorithmsMap.empty()) {
129 SUIT_ResourceMgr* resMgr = SMESHGUI::resourceMgr();
132 // Find name of a resource XML file ("SMESH_Meshers.xml");
134 char* cenv = getenv("SMESH_MeshersList");
136 HypsXml.sprintf("%s", cenv);
138 QStringList HypsXmlList = QStringList::split(":", HypsXml, false);
139 if (HypsXmlList.count() == 0)
141 SUIT_MessageBox::error1(SMESHGUI::desktop(),
142 QObject::tr("SMESH_WRN_WARNING"),
143 QObject::tr("MESHERS_FILE_NO_VARIABLE"),
144 QObject::tr("SMESH_BUT_OK"));
148 // loop on files in HypsXml
149 QString aNoAccessFiles;
150 for (int i = 0; i < HypsXmlList.count(); i++) {
151 QString HypsXml = HypsXmlList[ i ];
153 // Find full path to the resource XML file
154 QString xmlFile = resMgr->path("resources", "SMESH", HypsXml + ".xml");
155 if ( xmlFile.isEmpty() ) // try PLUGIN resources
156 xmlFile = resMgr->path("resources", HypsXml, HypsXml + ".xml");
158 QFile file (xmlFile);
159 if (file.exists() && file.open(IO_ReadOnly)) {
162 SMESHGUI_XmlHandler* aXmlHandler = new SMESHGUI_XmlHandler();
165 QXmlInputSource source (file);
166 QXmlSimpleReader reader;
167 reader.setContentHandler(aXmlHandler);
168 reader.setErrorHandler(aXmlHandler);
169 bool ok = reader.parse(source);
172 myHypothesesMap.insert( aXmlHandler->myHypothesesMap.begin(),
173 aXmlHandler->myHypothesesMap.end() );
174 myAlgorithmsMap.insert( aXmlHandler->myAlgorithmsMap.begin(),
175 aXmlHandler->myAlgorithmsMap.end() );
176 myListOfHypothesesSets.splice( myListOfHypothesesSets.begin(),
177 aXmlHandler->myListOfHypothesesSets );
180 SUIT_MessageBox::error1(SMESHGUI::desktop(),
181 QObject::tr("INF_PARSE_ERROR"),
182 QObject::tr(aXmlHandler->errorProtocol()),
183 QObject::tr("SMESH_BUT_OK"));
187 if (aNoAccessFiles.isEmpty())
188 aNoAccessFiles = xmlFile;
190 aNoAccessFiles += ", " + xmlFile;
195 if (!aNoAccessFiles.isEmpty()) {
196 QString aMess = QObject::tr("MESHERS_FILE_CANT_OPEN") + " " + aNoAccessFiles + "\n";
197 aMess += QObject::tr("MESHERS_FILE_CHECK_VARIABLE");
199 SUIT_MessageBox::warn1(SMESHGUI::desktop(),
200 QObject::tr("SMESH_WRN_WARNING"),
202 QObject::tr("SMESH_BUT_OK"));
209 QStringList GetAvailableHypotheses( const bool isAlgo,
213 QStringList aHypList;
215 // Init list of available hypotheses, if needed
216 InitAvailableHypotheses();
218 // fill list of hypotheses/algorithms
219 THypothesisDataMap* pMap = isAlgo ? &myAlgorithmsMap : &myHypothesesMap;
220 THypothesisDataMap::iterator anIter;
221 for ( anIter = pMap->begin(); anIter != pMap->end(); anIter++ )
223 HypothesisData* aData = (*anIter).second;
224 if ( ( theDim < 0 || aData->Dim.contains( theDim ) ) && aData->IsAux == isAux )
225 aHypList.append(((*anIter).first).c_str());
231 QStringList GetHypothesesSets()
233 QStringList aSetNameList;
235 // Init list of available hypotheses, if needed
236 InitAvailableHypotheses();
238 list<HypothesesSet*>::iterator hypoSet = myListOfHypothesesSets.begin();
239 for ( ; hypoSet != myListOfHypothesesSets.end(); ++hypoSet )
241 HypothesesSet* aSet = *hypoSet;
242 if ( aSet && aSet->AlgoList.count() ) {
243 aSetNameList.append( aSet->HypoSetName );
250 HypothesesSet* GetHypothesesSet(const QString theSetName)
252 list<HypothesesSet*>::iterator hypoSet = myListOfHypothesesSets.begin();
253 for ( ; hypoSet != myListOfHypothesesSets.end(); ++hypoSet )
255 HypothesesSet* aSet = *hypoSet;
256 if ( aSet && aSet->HypoSetName == theSetName )
262 HypothesisData* GetHypothesisData (const char* aHypType)
264 HypothesisData* aHypData = 0;
266 // Init list of available hypotheses, if needed
267 InitAvailableHypotheses();
269 if (myHypothesesMap.find(aHypType) == myHypothesesMap.end()) {
270 if (myAlgorithmsMap.find(aHypType) != myAlgorithmsMap.end()) {
271 aHypData = myAlgorithmsMap[aHypType];
275 aHypData = myHypothesesMap[aHypType];
281 SMESHGUI_GenericHypothesisCreator* GetHypothesisCreator(const char* aHypType)
283 if(MYDEBUG) MESSAGE("Get HypothesisCreator for " << aHypType);
285 SMESHGUI_GenericHypothesisCreator* aCreator = 0;
287 // check, if creator for this hypothesis type already exists
288 if (myHypCreatorMap.find(aHypType) != myHypCreatorMap.end()) {
289 aCreator = myHypCreatorMap[aHypType];
292 // 1. Init list of available hypotheses, if needed
293 InitAvailableHypotheses();
295 // 2. Get names of plugin libraries
296 HypothesisData* aHypData = GetHypothesisData(aHypType);
299 QString aClientLibName = aHypData->ClientLibName;
300 QString aServerLibName = aHypData->ServerLibName;
302 // 3. Load Client Plugin Library
304 // load plugin library
305 if(MYDEBUG) MESSAGE("Loading client meshers plugin library ...");
306 LibHandle libHandle = LoadLib( aClientLibName );
308 // report any error, if occured
312 const char* anError = "Can't load client meshers plugin library";
314 const char* anError = dlerror();
320 // get method, returning hypothesis creator
321 if(MYDEBUG) MESSAGE("Find GetHypothesisCreator() method ...");
322 typedef SMESHGUI_GenericHypothesisCreator* (*GetHypothesisCreator) \
324 GetHypothesisCreator procHandle =
325 (GetHypothesisCreator)GetProc(libHandle, "GetHypothesisCreator");
327 if(MYDEBUG) MESSAGE("bad hypothesis client plugin library");
328 UnLoadLib(libHandle);
331 // get hypothesis creator
332 if(MYDEBUG) MESSAGE("Get Hypothesis Creator for " << aHypType);
333 aCreator = procHandle( aHypType );
335 if(MYDEBUG) MESSAGE("no such a hypothesis in this plugin");
338 // map hypothesis creator to a hypothesis name
339 myHypCreatorMap[aHypType] = aCreator;
344 catch (const SALOME::SALOME_Exception& S_ex) {
345 SalomeApp_Tools::QtCatchCorbaException(S_ex);
353 SMESH::SMESH_Hypothesis_ptr CreateHypothesis(const char* aHypType,
354 const char* aHypName,
357 if(MYDEBUG) MESSAGE("Create " << aHypType << " with name " << aHypName);
359 SMESH::SMESH_Hypothesis_var Hyp;
361 HypothesisData* aHypData = GetHypothesisData(aHypType);
362 QString aServLib = aHypData->ServerLibName;
365 Hyp = SMESHGUI::GetSMESHGen()->CreateHypothesis(aHypType, aServLib);
366 if (!Hyp->_is_nil()) {
367 _PTR(SObject) SHyp = SMESH::FindSObject(Hyp.in());
369 //if (strcmp(aHypName,"") != 0)
370 if (strlen(aHypName) > 0)
371 SMESH::SetName(SHyp, aHypName);
372 //SalomeApp_Application* app =
373 // dynamic_cast<SalomeApp_Application*>(SUIT_Session::session()->activeApplication());
375 // app->objectBrowser()->updateTree();
376 SMESHGUI::GetSMESHGUI()->updateObjBrowser();
381 catch (const SALOME::SALOME_Exception & S_ex) {
382 SalomeApp_Tools::QtCatchCorbaException(S_ex);
385 return SMESH::SMESH_Hypothesis::_nil();
389 bool AddHypothesisOnMesh (SMESH::SMESH_Mesh_ptr aMesh, SMESH::SMESH_Hypothesis_ptr aHyp)
391 if(MYDEBUG) MESSAGE ("SMESHGUI::AddHypothesisOnMesh");
392 int res = SMESH::HYP_UNKNOWN_FATAL;
393 SUIT_OverrideCursor wc;
395 if (!aMesh->_is_nil()) {
396 _PTR(SObject) SM = SMESH::FindSObject(aMesh);
397 GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(SM);
399 res = aMesh->AddHypothesis(aShapeObject, aHyp);
400 if (res < SMESH::HYP_UNKNOWN_FATAL) {
401 _PTR(SObject) SH = SMESH::FindSObject(aHyp);
403 SMESH::ModifiedMesh(SM, false);
406 if (res > SMESH::HYP_OK) {
408 processHypothesisStatus(res, aHyp, true);
412 catch(const SALOME::SALOME_Exception& S_ex) {
414 SalomeApp_Tools::QtCatchCorbaException(S_ex);
415 res = SMESH::HYP_UNKNOWN_FATAL;
418 return res < SMESH::HYP_UNKNOWN_FATAL;
422 bool AddHypothesisOnSubMesh (SMESH::SMESH_subMesh_ptr aSubMesh, SMESH::SMESH_Hypothesis_ptr aHyp)
424 if(MYDEBUG) MESSAGE("SMESHGUI::AddHypothesisOnSubMesh() ");
425 int res = SMESH::HYP_UNKNOWN_FATAL;
426 SUIT_OverrideCursor wc;
428 if (!aSubMesh->_is_nil() && ! aHyp->_is_nil()) {
430 SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
431 _PTR(SObject) SsubM = SMESH::FindSObject(aSubMesh);
432 GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(SsubM);
433 if (!aMesh->_is_nil() && SsubM && !aShapeObject->_is_nil()) {
434 res = aMesh->AddHypothesis(aShapeObject, aHyp);
435 if (res < SMESH::HYP_UNKNOWN_FATAL) {
436 _PTR(SObject) meshSO = SMESH::FindSObject(aMesh);
438 SMESH::ModifiedMesh(meshSO, false);
440 if (res > SMESH::HYP_OK) {
442 processHypothesisStatus(res, aHyp, true);
447 SCRUTE(aHyp->_is_nil());
448 SCRUTE(aMesh->_is_nil());
450 SCRUTE(aShapeObject->_is_nil());
453 catch(const SALOME::SALOME_Exception& S_ex) {
455 SalomeApp_Tools::QtCatchCorbaException(S_ex);
456 res = SMESH::HYP_UNKNOWN_FATAL;
460 SCRUTE(aSubMesh->_is_nil());
461 SCRUTE(aHyp->_is_nil());
463 return res < SMESH::HYP_UNKNOWN_FATAL;
466 bool RemoveHypothesisOrAlgorithmOnMesh (const Handle(SALOME_InteractiveObject)& IObject)
468 int res = SMESH::HYP_UNKNOWN_FATAL;
469 SUIT_OverrideCursor wc;
472 _PTR(Study) aStudy = GetActiveStudyDocument();
473 _PTR(SObject) aHypObj = aStudy->FindObjectID( IObject->getEntry() );
476 _PTR(SObject) MorSM = SMESH::GetMeshOrSubmesh( aHypObj );
477 _PTR(SObject) aRealHypo;
478 if( aHypObj->ReferencedObject( aRealHypo ) )
480 SMESH_Hypothesis_var hypo = SMESH_Hypothesis::_narrow( SObjectToObject( aRealHypo ) );
481 RemoveHypothesisOrAlgorithmOnMesh( MorSM, hypo );
485 SMESH_Hypothesis_var hypo = SMESH_Hypothesis::_narrow( SObjectToObject( aHypObj ) );
486 SObjectList meshList = GetMeshesUsingAlgoOrHypothesis( hypo );
487 for( int i = 0; i < meshList.size(); i++ )
488 RemoveHypothesisOrAlgorithmOnMesh( meshList[ i ], hypo );
492 catch(const SALOME::SALOME_Exception& S_ex)
495 SalomeApp_Tools::QtCatchCorbaException(S_ex);
496 res = SMESH::HYP_UNKNOWN_FATAL;
498 return res < SMESH::HYP_UNKNOWN_FATAL;
501 bool RemoveHypothesisOrAlgorithmOnMesh (_PTR(SObject) MorSM,
502 SMESH::SMESH_Hypothesis_ptr anHyp)
504 SALOMEDS::GenericAttribute_var anAttr;
505 SALOMEDS::AttributeIOR_var anIOR;
506 int res = SMESH::HYP_UNKNOWN_FATAL;
507 SUIT_OverrideCursor wc;
511 GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(MorSM);
512 if (!aShapeObject->_is_nil()) {
513 SMESH::SMESH_Mesh_var aMesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>(MorSM);
514 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SObjectToInterface<SMESH::SMESH_subMesh>(MorSM);
516 if (!aSubMesh->_is_nil())
517 aMesh = aSubMesh->GetFather();
519 if (!aMesh->_is_nil()) {
520 res = aMesh->RemoveHypothesis(aShapeObject, anHyp);
521 if (res < SMESH::HYP_UNKNOWN_FATAL) {
522 _PTR(SObject) meshSO = SMESH::FindSObject(aMesh);
524 SMESH::ModifiedMesh(meshSO, false);
526 if (res > SMESH::HYP_OK) {
528 processHypothesisStatus(res, anHyp, false);
533 } catch(const SALOME::SALOME_Exception& S_ex) {
535 SalomeApp_Tools::QtCatchCorbaException(S_ex);
536 res = SMESH::HYP_UNKNOWN_FATAL;
539 return res < SMESH::HYP_UNKNOWN_FATAL;
542 SObjectList GetMeshesUsingAlgoOrHypothesis(SMESH::SMESH_Hypothesis_ptr AlgoOrHyp)
544 SObjectList listSOmesh;
545 listSOmesh.resize(0);
547 unsigned int index = 0;
548 if (!AlgoOrHyp->_is_nil()) {
549 _PTR(SObject) SO_Hypothesis = SMESH::FindSObject(AlgoOrHyp);
552 SMESHGUI::activeStudy()->studyDS()->FindDependances(SO_Hypothesis);
554 if(MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency number ="<<listSO.size());
555 for (unsigned int i = 0; i < listSO.size(); i++) {
556 _PTR(SObject) SO = listSO[i];
558 _PTR(SObject) aFather = SO->GetFather();
560 _PTR(SObject) SOfatherFather = aFather->GetFather();
561 if (SOfatherFather) {
562 if(MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency added to list");
564 listSOmesh.resize(index);
565 listSOmesh[index - 1] = SOfatherFather;
572 if (MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): completed");
576 #define CASE2MESSAGE(enum) case SMESH::enum: msg = QObject::tr( #enum ); break;
577 QString GetMessageOnAlgoStateErrors(const algo_error_array& errors)
579 QString resMsg = QObject::tr("SMESH_WRN_MISSING_PARAMETERS") + ":\n";
580 for ( int i = 0; i < errors.length(); ++i ) {
581 const SMESH::AlgoStateError & error = errors[ i ];
583 switch( error.name ) {
584 CASE2MESSAGE( MISSING_ALGO );
585 CASE2MESSAGE( MISSING_HYPO );
586 CASE2MESSAGE( NOT_CONFORM_MESH );
589 // apply args to message:
591 if ( error.algoName.in() != 0 )
592 msg = msg.arg( error.algoName.in() );
594 msg = msg.arg( error.algoDim );
596 msg = msg.arg( QObject::tr( error.isGlobalAlgo ? "GLOBAL_ALGO" : "LOCAL_ALGO" ));
597 // %4 - hypothesis dim == algoDim
598 msg = msg.arg( error.algoDim );
600 if ( i ) resMsg += ";\n";