Salome HOME
0022876: EDF 8425 SMESH: Get the normal of a face in the GUI
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_MeshOp.cxx
1 // Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //  File   : SMESHGUI_MeshOp.cxx
23 //  Author : Sergey LITONIN, Open CASCADE S.A.S.
24
25 // SMESH includes
26 #include "SMESHGUI_MeshOp.h"
27
28 #include "SMESHGUI.h"
29 #include "SMESHGUI_GEOMGenUtils.h"
30 #include "SMESHGUI_Hypotheses.h"
31 #include "SMESHGUI_HypothesesUtils.h"
32 #include "SMESHGUI_MeshDlg.h"
33 #include "SMESHGUI_Operations.h"
34 #include "SMESHGUI_ShapeByMeshDlg.h"
35 #include "SMESHGUI_Utils.h"
36 #include "SMESH_NumberFilter.hxx"
37 #include "SMESH_TypeFilter.hxx"
38
39 // SALOME GEOM includes
40 #include <GEOM_SelectionFilter.h>
41 #include <GEOMBase.h>
42 #include <GeometryGUI.h>
43 #include <GEOM_wrap.hxx>
44 #include <GEOMImpl_Types.hxx>
45
46 // SALOME GUI includes
47 #include <SalomeApp_Tools.h>
48 #include <SalomeApp_Application.h>
49 #include <LightApp_Application.h>
50 #include <LightApp_SelectionMgr.h>
51 #include <LightApp_UpdateFlags.h>
52 #include <SUIT_MessageBox.h>
53 #include <SUIT_OverrideCursor.h>
54 #include <SUIT_Session.h>
55 #include <SALOME_InteractiveObject.hxx>
56 #include <SALOME_ListIO.hxx>
57
58 // SALOME KERNEL includes
59 #include <SALOMEDS_SComponent.hxx>
60 #include <SALOMEDS_SObject.hxx>
61 #include <SALOMEDS_Study.hxx>
62 #include <SALOMEDS_wrap.hxx>
63
64 // Qt includes
65 #include <QStringList>
66 #include <QLineEdit>
67 #include <QApplication>
68
69 // OCCT includes
70 #include <TopoDS.hxx>
71 #include <TopoDS_Shape.hxx>
72 #include <TopoDS_Shell.hxx>
73 #include <TopExp_Explorer.hxx>
74 #include <BRep_Tool.hxx>
75
76 // IDL includes
77 #include <SALOMEconfig.h>
78 #include CORBA_CLIENT_HEADER(SMESH_Gen)
79
80 //================================================================================
81 /*!
82  * \brief Constructor
83   * \param theToCreate - if this parameter is true then operation is used for creation,
84   * for editing otherwise
85  *
86  * Initialize operation
87 */
88 //================================================================================
89 SMESHGUI_MeshOp::SMESHGUI_MeshOp( const bool theToCreate, const bool theIsMesh )
90 : SMESHGUI_SelectionOp(),
91   myToCreate( theToCreate ),
92   myIsMesh( theIsMesh ),
93   myDlg( 0 ),
94   myShapeByMeshOp( 0 ),
95   myHypoSet( 0 )
96 {
97   if ( GeometryGUI::GetGeomGen()->_is_nil() )// check that GEOM_Gen exists
98     GeometryGUI::InitGeomGen();
99   myIsOnGeometry = true;
100   myMaxShapeDim = -1;
101 }
102
103 //================================================================================
104 /*!
105  * \brief Destructor
106 */
107 //================================================================================
108 SMESHGUI_MeshOp::~SMESHGUI_MeshOp()
109 {
110   if ( myDlg )
111     delete myDlg;
112 }
113
114 //================================================================================
115 /*!
116  * \brief Gets dialog of this operation
117   * \retval LightApp_Dialog* - pointer to dialog of this operation
118 */
119 //================================================================================
120 LightApp_Dialog* SMESHGUI_MeshOp::dlg() const
121 {
122   return myDlg;
123 }
124
125 //================================================================================
126 /*!
127  * \brief Creates or edits mesh
128   * \retval bool - TRUE if operation is performed successfully, FALSE otherwise
129  *
130  * Virtual slot redefined from the base class called when "Apply" button is clicked
131  * creates or edits mesh
132  */
133 //================================================================================
134 bool SMESHGUI_MeshOp::onApply()
135 {
136   if (isStudyLocked())
137     return false;
138
139   QString aMess;
140   if ( !isValid( aMess ) )
141   {
142     dlg()->show();
143     if ( aMess != "" )
144       SUIT_MessageBox::warning( myDlg, tr( "SMESH_WRN_WARNING" ), aMess );
145     return false;
146   }
147
148   bool aResult = false;
149   aMess = "";
150   try
151   {
152     QStringList anEntryList;
153     if ( myToCreate && myIsMesh )
154       aResult = createMesh( aMess, anEntryList );
155     if ( myToCreate && !myIsMesh )
156       aResult = createSubMesh( aMess, anEntryList );
157     else if ( !myToCreate )
158       aResult = editMeshOrSubMesh( aMess );
159     if ( aResult )
160     {
161       SMESHGUI::Modified();
162       update( UF_ObjBrowser | UF_Model );
163       if( LightApp_Application* anApp =
164           dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
165         myObjectToSelect = anApp->browseObjects( anEntryList, isApplyAndClose() );
166     }
167   }
168   catch ( const SALOME::SALOME_Exception& S_ex )
169   {
170     SalomeApp_Tools::QtCatchCorbaException( S_ex );
171     aResult = false;
172   }
173   catch ( ... )
174   {
175     aResult = false;
176   }
177
178   if ( aResult )
179   {
180     if ( myToCreate )
181       setDefaultName();
182   }
183   else
184   {
185     if ( aMess == "" )
186       aMess = tr( "SMESH_OPERATION_FAILED" );
187     SUIT_MessageBox::warning( myDlg, tr( "SMESH_ERROR" ), aMess );
188   }
189
190   return aResult;
191 }
192
193 //================================================================================
194 /*!
195  * \brief Creates dialog if necessary and shows it
196  *
197  * Virtual method redefined from base class called when operation is started creates
198  * dialog if necessary and shows it, activates selection
199  */
200 //================================================================================
201 void SMESHGUI_MeshOp::startOperation()
202 {
203   if (!myDlg)
204   {
205     myDlg = new SMESHGUI_MeshDlg( myToCreate, myIsMesh );
206     for ( int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++ )
207     {
208       connect( myDlg->tab( i ), SIGNAL( createHyp( const int, const int ) ),
209               this, SLOT( onCreateHyp( const int, const int ) ) );
210       connect( myDlg->tab( i ), SIGNAL( editHyp( const int, const int ) ),
211               this, SLOT( onEditHyp( const int, const int ) ) );
212       connect( myDlg->tab( i ), SIGNAL( selectAlgo( const int ) ),
213               this, SLOT( onAlgoSelected( const int ) ) );
214     }
215     connect( myDlg, SIGNAL( hypoSet( const QString& )), SLOT( onHypoSet( const QString& )));
216     connect( myDlg, SIGNAL( geomSelectionByMesh( bool )), SLOT( onGeomSelectionByMesh( bool )));
217     connect( myDlg, SIGNAL( selectMeshType( const int, const int ) ), SLOT( onAlgoSetByMeshType( const int, const int)));
218     if ( myToCreate ) {
219       if ( myIsMesh ) myHelpFileName = "constructing_meshes_page.html";
220       else            myHelpFileName = "constructing_submeshes_page.html";
221     }
222     else {
223       myHelpFileName = "editing_meshes_page.html";
224     }
225   }
226   SMESHGUI_SelectionOp::startOperation();
227   // iterate through dimensions and get available algoritms, set them to the dialog
228   _PTR(SComponent) aFather = SMESH::GetActiveStudyDocument()->FindComponent( "SMESH" );
229   for ( int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++ )
230   {
231     SMESHGUI_MeshTab* aTab = myDlg->tab( i );
232     QStringList hypList;
233     // clear available hypotheses
234     aTab->setAvailableHyps( MainHyp, hypList );
235     aTab->setAvailableHyps( AddHyp, hypList );
236     aTab->setExistingHyps( MainHyp, hypList );
237     aTab->setExistingHyps( AddHyp, hypList );
238     myExistingHyps[ i ][ MainHyp ].clear();
239     myExistingHyps[ i ][ AddHyp ].clear();
240     // set algos
241     availableHyps( i, Algo, hypList, myAvailableHypData[i][Algo] );
242     aTab->setAvailableHyps( Algo, hypList );
243   }
244   if ( myToCreate )
245   {
246     setDefaultName();
247     myDlg->activateObject( myIsMesh ? SMESHGUI_MeshDlg::Geom : SMESHGUI_MeshDlg::Mesh );
248   }
249   else
250   {
251     myDlg->activateObject( SMESHGUI_MeshDlg::Obj );
252   }
253   myDlg->setCurrentTab( SMESH::DIM_3D );
254
255   QStringList TypeMeshList;
256   createMeshTypeList( TypeMeshList );
257   setAvailableMeshType( TypeMeshList );
258
259   myDlg->show();
260   myDlg->setGeomPopupEnabled(false);
261   selectionDone();
262
263   myIgnoreAlgoSelection = false;
264   myHasConcurrentSubBefore = false;
265
266   myObjectToSelect.clear();
267 }
268
269 //=================================================================================
270 /*!
271  * \brief Selects a recently created mesh or sub-mesh if necessary
272  *
273  * Virtual method redefined from base class called when operation is commited
274  * selects a recently created mesh or sub-mesh if necessary. Allows to perform
275  * selection when the custom selection filters are removed.
276  */
277 //=================================================================================
278 void SMESHGUI_MeshOp::commitOperation()
279 {
280   SMESHGUI_SelectionOp::commitOperation();
281
282   if ( !myObjectToSelect.isEmpty() ) {
283     if ( LightApp_SelectionMgr* aSelectionMgr = selectionMgr() ) {
284       SUIT_DataOwnerPtrList aList;
285       aList.append( new LightApp_DataOwner( myObjectToSelect ) );
286       aSelectionMgr->setSelected( aList );
287     }
288   }
289 }
290
291 //================================================================================
292 /*!
293  * \brief Creates selection filter
294   * \param theId - identifier of current selection widget
295   * \retval SUIT_SelectionFilter* - pointer to the created filter or null
296  *
297  * Creates selection filter in accordance with identifier of current selection widget
298  */
299 //================================================================================
300 SUIT_SelectionFilter* SMESHGUI_MeshOp::createFilter( const int theId ) const
301 {
302   if ( theId == SMESHGUI_MeshDlg::Geom )
303   {
304 //     TColStd_MapOfInteger allTypesMap;
305 //     for ( int i = 0; i < 10; i++ )
306 //       allTypesMap.Add( i );
307 //     return new SMESH_NumberFilter( "GEOM", TopAbs_SHAPE, 0, allTypesMap );
308     return new GEOM_SelectionFilter( (SalomeApp_Study*)study(), true );
309   }
310   else if ( theId == SMESHGUI_MeshDlg::Obj && !myToCreate )
311     return new SMESH_TypeFilter( SMESH::MESHorSUBMESH );
312   else if ( theId == SMESHGUI_MeshDlg::Mesh )
313     return new SMESH_TypeFilter( SMESH::MESH );
314   else
315     return 0;
316 }
317
318 //================================================================================
319 /*!
320  * \brief check if selected shape is a sub-shape of the shape to mesh
321   * \retval bool - check result
322  */
323 //================================================================================
324 bool SMESHGUI_MeshOp::isSubshapeOk() const
325 {
326   if ( !myToCreate || myIsMesh ) // not submesh creation
327     return false;
328
329   // mesh
330   QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
331   _PTR(SObject) pMesh = studyDS()->FindObjectID( aMeshEntry.toLatin1().data() );
332   if (!pMesh) return false;
333
334   SMESH::SMESH_Mesh_var mesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( pMesh );
335   if (mesh->_is_nil()) return false;
336
337   // main shape of the mesh
338   GEOM::GEOM_Object_var mainGeom = mesh->GetShapeToMesh();
339   if (mainGeom->_is_nil()) return false;
340
341   // geometry
342   QStringList aGEOMs;
343   myDlg->selectedObject(SMESHGUI_MeshDlg::Geom, aGEOMs);
344
345   if (aGEOMs.count() > 0) {
346     GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen();
347     _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
348     if (geomGen->_is_nil() || !aStudy) return false;
349
350     GEOM::GEOM_IGroupOperations_wrap op = geomGen->GetIGroupOperations(aStudy->StudyId());
351     if (op->_is_nil()) return false;
352
353     // check all selected shapes
354     QStringList::const_iterator aSubShapesIter = aGEOMs.begin();
355     for ( ; aSubShapesIter != aGEOMs.end(); aSubShapesIter++) {
356       QString aSubGeomEntry = (*aSubShapesIter);
357       _PTR(SObject) pSubGeom = studyDS()->FindObjectID(aSubGeomEntry.toLatin1().data());
358       if (!pSubGeom) return false;
359
360       GEOM::GEOM_Object_var aSubGeomVar =
361         GEOM::GEOM_Object::_narrow(_CAST(SObject,pSubGeom)->GetObject());
362       if (aSubGeomVar->_is_nil()) return false;
363
364       // skl for NPAL14695 - implementation of searching of mainObj
365       GEOM::GEOM_Object_var mainObj = op->GetMainShape(aSubGeomVar); /* _var not _wrap as
366                                                                         mainObj already exists! */
367       while( !mainObj->_is_nil()) {
368         CORBA::String_var entry1 = mainObj->GetEntry();
369         CORBA::String_var entry2 = mainGeom->GetEntry();
370         if (std::string( entry1.in() ) == entry2.in() )
371           return true;
372         mainObj = op->GetMainShape(mainObj);
373       }
374       if ( aSubGeomVar->GetShapeType() == GEOM::COMPOUND )
375       {
376         // is aSubGeomVar a compound of sub-shapes?
377         GEOM::GEOM_IShapesOperations_wrap sop = geomGen->GetIShapesOperations(aStudy->StudyId());
378         if (sop->_is_nil()) return false;
379         GEOM::ListOfLong_var ids = sop->GetAllSubShapesIDs( aSubGeomVar,
380                                                             GEOM::SHAPE,/*sorted=*/false);
381         if ( ids->length() > 0 )
382         {
383           ids->length( 1 );
384           GEOM::GEOM_Object_var compSub = geomGen->AddSubShape( aSubGeomVar, ids );
385           if ( !compSub->_is_nil() )
386           {
387             GEOM::ListOfGO_var shared = sop->GetSharedShapes( mainGeom,
388                                                               compSub,
389                                                               compSub->GetShapeType() );
390             geomGen->RemoveObject( compSub );
391             compSub->UnRegister();
392             if ( shared->length() > 0 ) {
393               geomGen->RemoveObject( shared[0] );
394               shared[0]->UnRegister();
395             }
396             return ( shared->length() > 0 );
397           }
398         }
399       }
400     }
401   }
402
403   return false;
404 }
405
406 //================================================================================
407 /*!
408  * \brief Return name of the algorithm that does not support sub-meshes and makes
409  * sub-mesh creation useless
410  *  \retval char* - string is to be deleted!!!
411  */
412 //================================================================================
413 char* SMESHGUI_MeshOp::isSubmeshIgnored() const
414 {
415   if ( myToCreate && !myIsMesh ) {
416
417     QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
418     QString aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
419     _PTR(SObject) pMesh = studyDS()->FindObjectID( aMeshEntry.toLatin1().data() );
420     if ( pMesh ) {
421
422       QStringList algoNames;
423       THypList    algoList;
424       existingHyps(3, Algo, pMesh, algoNames, algoList);
425       if (!algoList.empty()) {
426         HypothesisData* algo =
427           SMESH::GetHypothesisData( SMESH::toQStr( algoList[0].first->GetName() ));
428         if ( algo &&
429              algo->InputTypes.empty() && // builds all dimensions it-self
430              !algo->IsSupportSubmeshes )
431           return CORBA::string_dup( algoNames[0].toLatin1().data() );
432       }
433
434 //       GEOM::GEOM_Object_var geom;
435 //       if (_PTR(SObject) pGeom = studyDS()->FindObjectID( aGeomEntry.toLatin1().data() ))
436 //         geom = SMESH::SObjectToInterface<GEOM::GEOM_Object>( pGeom );
437
438 //       if ( !geom->_is_nil() && geom->GetShapeType() >= GEOM::FACE ) { // WIRE, EDGE as well
439         existingHyps(2, Algo, pMesh, algoNames, algoList);
440         if (!algoList.empty()) {
441           HypothesisData* algo =
442             SMESH::GetHypothesisData( SMESH::toQStr( algoList[0].first->GetName() ));
443           if ( algo &&
444                algo->InputTypes.empty() && // builds all dimensions it-self
445                !algo->IsSupportSubmeshes )
446             return CORBA::string_dup( algoNames[0].toLatin1().data() );
447         }
448 //       }
449     }
450   }
451   return 0;
452 }
453
454 //================================================================================
455 /*!
456  * \brief find an existing submesh by the selected shape
457  * \retval _PTR(SObject) - the found submesh SObject
458  */
459 //================================================================================
460 _PTR(SObject) SMESHGUI_MeshOp::getSubmeshByGeom() const
461 {
462   QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
463   QString aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
464   _PTR(SObject) pMesh = studyDS()->FindObjectID( aMeshEntry.toLatin1().data() );
465   _PTR(SObject) pGeom = studyDS()->FindObjectID( aGeomEntry.toLatin1().data() );
466   if ( pMesh && pGeom ) {
467     GEOM::GEOM_Object_var geom = SMESH::SObjectToInterface<GEOM::GEOM_Object>( pGeom );
468     if ( !geom->_is_nil() ) {
469       int tag = -1;
470       switch ( geom->GetShapeType() ) {
471       case GEOM::VERTEX:   tag = SMESH::Tag_SubMeshOnVertex;   break;
472       case GEOM::EDGE:     tag = SMESH::Tag_SubMeshOnEdge;     break;
473       case GEOM::WIRE:     tag = SMESH::Tag_SubMeshOnWire;     break;
474       case GEOM::FACE:     tag = SMESH::Tag_SubMeshOnFace;     break;
475       case GEOM::SHELL:    tag = SMESH::Tag_SubMeshOnShell;    break;
476       case GEOM::SOLID:    tag = SMESH::Tag_SubMeshOnSolid;    break;
477       case GEOM::COMPOUND: tag = SMESH::Tag_SubMeshOnCompound; break;
478       default:;
479       }
480       _PTR(GenericAttribute) anAttr;
481       _PTR(SObject) aSubmeshRoot;
482       _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
483       if ( pMesh->FindSubObject( tag, aSubmeshRoot ) )
484       {
485         _PTR(ChildIterator) smIter = aStudy->NewChildIterator( aSubmeshRoot );
486         for ( ; smIter->More(); smIter->Next() )
487         {
488           _PTR(SObject) aSmObj = smIter->Value();
489           if ( ! aSmObj->FindAttribute( anAttr, "AttributeIOR" ))
490             continue;
491           _PTR(ChildIterator) anIter1 = aStudy->NewChildIterator(aSmObj);
492           for ( ; anIter1->More(); anIter1->Next()) {
493             _PTR(SObject) pGeom2 = anIter1->Value();
494             if ( pGeom2->ReferencedObject( pGeom2 ) &&
495                  pGeom2->GetID() == pGeom->GetID() )
496               return aSmObj;
497           }
498         }
499       }
500     }
501   }
502   return _PTR(SObject)();
503 }
504
505 //================================================================================
506 /*!
507  * \brief Updates dialog's look and feel
508  *
509  * Virtual method redefined from the base class updates dialog's look and feel
510  */
511 //================================================================================
512 void SMESHGUI_MeshOp::selectionDone()
513 {
514   if (!dlg()->isVisible() || !myDlg->isEnabled())
515     return;
516
517   SMESHGUI_SelectionOp::selectionDone();
518
519   try
520   {
521     myIsOnGeometry = true;
522
523     //Check geometry for mesh
524     QString anObjEntry = myDlg->selectedObject(SMESHGUI_MeshDlg::Obj);
525     _PTR(SObject) pObj = studyDS()->FindObjectID(anObjEntry.toLatin1().data());
526     if (pObj)
527     {
528       SMESH::SMESH_Mesh_var aMeshVar =
529         SMESH::SMESH_Mesh::_narrow(_CAST(SObject,pObj)->GetObject());
530       if (!aMeshVar->_is_nil()) {
531         if (!myToCreate && !aMeshVar->HasShapeToMesh())
532           myIsOnGeometry = false;
533       }
534     }
535
536     if (myIsOnGeometry)
537     {
538       // Enable tabs according to shape dimension
539
540       int shapeDim = 3;
541
542       QStringList aGEOMs;
543       myDlg->selectedObject(SMESHGUI_MeshDlg::Geom, aGEOMs);
544       GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO;
545
546       if (aGEOMs.count() > 0) {
547         // one or more GEOM shape selected
548         aSeq->length(aGEOMs.count());
549         QStringList::const_iterator aSubShapesIter = aGEOMs.begin();
550         int iSubSh = 0;
551         for ( ; aSubShapesIter != aGEOMs.end(); aSubShapesIter++, iSubSh++) {
552           QString aSubGeomEntry = (*aSubShapesIter);
553           _PTR(SObject) pSubGeom = studyDS()->FindObjectID(aSubGeomEntry.toLatin1().data());
554           GEOM::GEOM_Object_var aSubGeomVar =
555             GEOM::GEOM_Object::_narrow(_CAST(SObject,pSubGeom)->GetObject());
556           aSeq[iSubSh] = aSubGeomVar;
557         }
558       } else {
559         // get geometry by selected sub-mesh
560         QString anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
561         _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() );
562         GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj );
563         if (!aGeomVar->_is_nil()) {
564           aSeq->length(1);
565           aSeq[0] = aGeomVar;
566         }
567       }
568
569       if (aSeq->length() > 0) {
570         shapeDim = -1;
571         for (int iss = 0; iss < aSeq->length() && shapeDim < 3; iss++) {
572           GEOM::GEOM_Object_var aGeomVar = aSeq[iss];
573           switch ( aGeomVar->GetShapeType() ) {
574           case GEOM::SOLID:  shapeDim = 3; break;
575           case GEOM::SHELL:
576             // Bug 0016155: EDF PAL 447: If the shape is a Shell, disable 3D tab
577             // {
578             //   TopoDS_Shape aShape;
579             //   bool isClosed = GEOMBase::GetShape(aGeomVar, aShape) && /*aShape.Closed()*/BRep_Tool::IsClosed(aShape);
580             //   shapeDim = qMax(isClosed ? 3 : 2, shapeDim);
581             // }
582             // break;
583           case GEOM::FACE:   shapeDim = qMax(2, shapeDim); break;
584           case GEOM::WIRE:
585           case GEOM::EDGE:   shapeDim = qMax(1, shapeDim); break;
586           case GEOM::VERTEX: shapeDim = qMax(0, shapeDim); break;
587           default:
588             {
589               TopoDS_Shape aShape;
590               if (GEOMBase::GetShape(aGeomVar, aShape))
591               {
592                 TopExp_Explorer exp (aShape, TopAbs_SOLID);
593                 if (exp.More()) {
594                   shapeDim = 3;
595                 }
596                 // Bug 0016155: EDF PAL 447: If the shape is a Shell, disable 3D tab
597                 // else if ( exp.Init( aShape, TopAbs_SHELL ), exp.More() )
598                 // {
599                 //   shapeDim = 2;
600                 //   for (; exp.More() && shapeDim == 2; exp.Next()) {
601                 //     if (/*exp.Current().Closed()*/BRep_Tool::IsClosed(exp.Current()))
602                 //       shapeDim = 3;
603                 //   }
604                 // }
605                 else if ( exp.Init( aShape, TopAbs_FACE ), exp.More() )
606                   shapeDim = qMax(2, shapeDim);
607                 else if ( exp.Init( aShape, TopAbs_EDGE ), exp.More() )
608                   shapeDim = qMax(1, shapeDim);
609                 else if ( exp.Init( aShape, TopAbs_VERTEX ), exp.More() )
610                   shapeDim = qMax(0, shapeDim);
611               }
612             }
613           }
614           if ( shapeDim == 3 )
615             break;
616         }
617       }
618       for (int i = SMESH::DIM_3D; i > shapeDim; i--) {
619         // reset algos before disabling tabs (0020138)
620         onAlgoSelected(-1, i);
621       }
622       myDlg->setMaxHypoDim( shapeDim );
623       myMaxShapeDim = shapeDim;
624       myDlg->setHypoSets( SMESH::GetHypothesesSets( shapeDim ));
625
626       if (!myToCreate) // edition: read hypotheses
627       {
628         if (pObj != 0)
629         {
630           SMESH::SMESH_subMesh_var submeshVar =
631             SMESH::SMESH_subMesh::_narrow( _CAST( SObject,pObj )->GetObject() );
632           myDlg->setObjectShown( SMESHGUI_MeshDlg::Mesh, !submeshVar->_is_nil() );
633           myDlg->setObjectShown( SMESHGUI_MeshDlg::Geom, true );
634           myDlg->objectWg( SMESHGUI_MeshDlg::Mesh, SMESHGUI_MeshDlg::Btn )->hide();
635           myDlg->objectWg( SMESHGUI_MeshDlg::Geom, SMESHGUI_MeshDlg::Btn )->hide();
636           myDlg->updateGeometry();
637           myDlg->adjustSize();
638           myIsMesh = submeshVar->_is_nil();
639           readMesh();
640         }
641         else
642           myDlg->reset();
643       }
644       else if ( !myIsMesh ) // submesh creation
645       {
646         // if a submesh on the selected shape already exist, pass to submesh edition mode
647         if ( _PTR(SObject) pSubmesh = getSubmeshByGeom() ) {
648           SMESH::SMESH_subMesh_var sm =
649             SMESH::SObjectToInterface<SMESH::SMESH_subMesh>( pSubmesh );
650           bool editSubmesh = ( !sm->_is_nil() &&
651                                SUIT_MessageBox::question( myDlg, tr( "SMESH_WARNING" ),
652                                                           tr( "EDIT_SUBMESH_QUESTION"),
653                                                           SUIT_MessageBox::Yes |
654                                                           SUIT_MessageBox::No,
655                                                           SUIT_MessageBox::No )
656                                == SUIT_MessageBox::Yes );
657           if ( editSubmesh )
658           {
659             selectionMgr()->clearFilters();
660             selectObject( pSubmesh );
661             SMESHGUI::GetSMESHGUI()->switchToOperation(704);
662             return;
663           }
664           else
665           {
666             myDlg->selectObject( "", SMESHGUI_MeshDlg::Geom, "" );
667             selectObject( _PTR(SObject)() );
668             selectionDone();
669             return;
670           }
671         }
672         // discard selected mesh if submesh creation not allowed because of
673         // a global algorithm that does not support submeshes
674         if ( char* algoName = isSubmeshIgnored() ) {
675           SUIT_MessageBox::warning( myDlg, tr( "SMESH_ERROR" ),
676                                     tr("SUBMESH_NOT_ALLOWED").arg(algoName));
677           CORBA::string_free( algoName );
678           myDlg->selectObject( "", SMESHGUI_MeshDlg::Mesh, "" );
679           selectObject( _PTR(SObject)() );
680           selectionDone();
681           return;
682         }
683
684         // enable/disable popup for choice of geom selection way
685         bool enable = false;
686         QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
687         if ( _PTR(SObject) pMesh = studyDS()->FindObjectID( aMeshEntry.toLatin1().data() )) {
688           SMESH::SMESH_Mesh_var mesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( pMesh );
689           if ( !mesh->_is_nil() ) {
690             //rnv: issue 21056: EDF 1608 SMESH: Dialog Box "Create Sub Mesh": focus should automatically switch to geometry
691             QString aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
692             _PTR(SObject) pGeom = studyDS()->FindObjectID( aGeomEntry.toLatin1().data() );
693             if ( !pGeom || GEOM::GEOM_Object::_narrow( _CAST( SObject,pGeom )->GetObject() )->_is_nil() )
694               myDlg->activateObject(SMESHGUI_MeshDlg::Geom);
695             enable = ( shapeDim > 1 ) && ( mesh->NbEdges() > 0 );
696           }
697         }
698         myDlg->setGeomPopupEnabled( enable );
699       }
700     }
701     else { // no geometry defined
702       myDlg->enableTab( SMESH::DIM_3D );
703       QStringList hypList;
704       availableHyps( SMESH::DIM_3D, Algo, hypList,
705                      myAvailableHypData[SMESH::DIM_3D][Algo]);
706
707       SMESHGUI_MeshTab* aTab = myDlg->tab( SMESH::DIM_3D );
708       aTab->setAvailableHyps( Algo, hypList );
709       for (int i = SMESH::DIM_0D;i < SMESH::DIM_3D; ++i) {
710         myDlg->disableTab(i);
711       }
712       myMaxShapeDim = -1;
713       //Hide labels and fields (Mesh and Geometry)
714       myDlg->setObjectShown( SMESHGUI_MeshDlg::Mesh, false );
715       myDlg->setObjectShown( SMESHGUI_MeshDlg::Geom, false );
716       myDlg->adjustSize();
717       readMesh();
718     }
719     int curIndex = myDlg->currentMeshType( );
720     QStringList TypeMeshList;
721     createMeshTypeList( TypeMeshList );
722     setAvailableMeshType( TypeMeshList );
723     curIndex =( curIndex >= TypeMeshList.count() ) ? 0 : curIndex;
724     myDlg->setCurrentMeshType( curIndex );
725     setFilteredAlgoData( myMaxShapeDim, curIndex);
726   }
727   catch ( const SALOME::SALOME_Exception& S_ex )
728   {
729     SalomeApp_Tools::QtCatchCorbaException( S_ex );
730   }
731   catch ( ... )
732   {
733   }
734 }
735
736 //================================================================================
737 /*!
738  * \brief Verifies validity of input data
739   * \param theMess - Output parameter intended for returning error message
740   * \retval bool  - TRUE if input data is valid, false otherwise
741  *
742  * Verifies validity of input data. This method is called when "Apply" or "OK" button
743  * is pressed before mesh creation or editing.
744  */
745 //================================================================================
746 bool SMESHGUI_MeshOp::isValid( QString& theMess ) const
747 {
748   // Selected object to be  edited
749   if ( !myToCreate && myDlg->selectedObject( SMESHGUI_MeshDlg::Obj ) == "" )
750   {
751     theMess = tr( "THERE_IS_NO_OBJECT_FOR_EDITING" );
752     return false;
753   }
754
755   // Name
756   QString aMeshName = myDlg->objectText( SMESHGUI_MeshDlg::Obj ).trimmed();
757   if ( aMeshName.isEmpty() )
758   {
759     theMess = myIsMesh ? tr( "NAME_OF_MESH_IS_EMPTY" ) : tr( "NAME_OF_SUBMESH_IS_EMPTY" );
760     return false;
761   }
762
763 /*  // Imported mesh, if create sub-mesh or edit mesh
764   if ( !myToCreate || ( myToCreate && !myIsMesh ))
765   {
766     QString aMeshEntry = myDlg->selectedObject
767       ( myToCreate ? SMESHGUI_MeshDlg::Mesh : SMESHGUI_MeshDlg::Obj );
768     if ( _PTR(SObject) pMesh = studyDS()->FindObjectID( aMeshEntry.toLatin1().data() )) {
769       SMESH::SMESH_Mesh_var mesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( pMesh );
770       if ( !mesh->_is_nil() && CORBA::is_nil( mesh->GetShapeToMesh() )) {
771         theMess = tr( "IMPORTED_MESH" );
772         return false;
773       }
774     }
775   }*/
776
777   // Geom
778   if ( myToCreate )
779   {
780     QString aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
781     if ( aGeomEntry.isEmpty() )
782     {
783       theMess = tr( myIsMesh ?
784                     "GEOMETRY_OBJECT_IS_NOT_DEFINED_MESH" :
785                     "GEOMETRY_OBJECT_IS_NOT_DEFINED_SUBMESH");
786       if ( !myIsMesh )
787         return false;
788       dlg()->show();
789       if ( SUIT_MessageBox::warning( myDlg, tr( "SMESH_WRN_WARNING" ), theMess,
790            SUIT_MessageBox::Yes, SUIT_MessageBox::No ) == SUIT_MessageBox::No )
791       {
792         theMess = "";
793         return false;
794       }
795       return true;
796     }
797     _PTR(SObject) pGeom = studyDS()->FindObjectID( aGeomEntry.toLatin1().data() );
798     if ( !pGeom || GEOM::GEOM_Object::_narrow( _CAST( SObject,pGeom )->GetObject() )->_is_nil() )
799     {
800       theMess = tr( "GEOMETRY_OBJECT_IS_NULL" );
801       return false;
802     }
803
804     // Mesh
805     if ( !myIsMesh ) // i.e sub-mesh creation,
806     {
807       QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
808       if ( aMeshEntry == "" )
809       {
810         theMess = tr( "MESH_IS_NOT_DEFINED" );
811         return false;
812       }
813       _PTR(SObject) pMesh = studyDS()->FindObjectID( aMeshEntry.toLatin1().data() );
814       if ( !pMesh || SMESH::SMESH_Mesh::_narrow( _CAST( SObject,pMesh )->GetObject() )->_is_nil() )
815       {
816         theMess = tr( "MESH_IS_NULL" );
817         return false;
818       }
819       if ( !isSubshapeOk() )
820       {
821         theMess = tr( "INVALID_SUBSHAPE" );
822         return false;
823       }
824     }
825   }
826
827   return true;
828 }
829
830 //================================================================================
831 /*!
832  * \brief check compatibility of the algorithm and another algorithm or hypothesis
833   * \param theAlgoData - algorithm data
834   * \param theHypData - hypothesis data
835   * \param theHypType - hypothesis type
836   * \param theHypTypeName - hypothesis type name, must be provided if 2-nd arg is not algo
837   * \retval bool - check result
838  */
839 //================================================================================
840 static bool isCompatible(const HypothesisData* theAlgoData,
841                          const HypothesisData* theHypData,
842                          const int             theHypType)
843 {
844   if ( !theAlgoData )
845     return true;
846
847   if ( theHypType == SMESHGUI_MeshOp::Algo )
848     return SMESH::IsCompatibleAlgorithm( theAlgoData, theHypData );
849
850   bool isOptional;
851   return ( SMESH::IsAvailableHypothesis( theAlgoData, theHypData->TypeName, isOptional ));
852 }
853
854 //================================================================================
855 /*!
856  * \brief Gets available hypotheses or algorithms
857   * \param theDim - specifies dimension of returned hypotheses/algorifms
858   * \param theHypType - specifies whether algorims or hypotheses or additional ones
859   * are retrieved (possible values are in HypType enumeration)
860   * \param theHyps - Output list of hypotheses' names
861   * \param theAlgoData - to select hypos able to be used by this algo (optional)
862  *
863  * Gets available hypotheses or algorithm in accordance with input parameters
864  */
865 //================================================================================
866 void SMESHGUI_MeshOp::availableHyps( const int       theDim,
867                                      const int       theHypType,
868                                      QStringList&    theHyps,
869                                      THypDataList&   theDataList,
870                                      HypothesisData* theAlgoData ) const
871 {
872   theDataList.clear();
873   theHyps.clear();
874   bool isAlgo = ( theHypType == Algo );
875   bool isAux  = ( theHypType >= AddHyp );
876   QStringList aHypTypeNameList = SMESH::GetAvailableHypotheses( isAlgo, theDim, isAux, myIsOnGeometry, !myIsMesh );
877
878   QStringList::const_iterator anIter;
879   for ( anIter = aHypTypeNameList.begin(); anIter != aHypTypeNameList.end(); ++anIter )
880   {
881     HypothesisData* aData = SMESH::GetHypothesisData( *anIter );
882     if ( isCompatible ( theAlgoData, aData, theHypType )) {
883       theDataList.append( aData );
884       theHyps.append( aData->Label );
885     }
886   }
887 }
888
889 //================================================================================
890 /*!
891  * \brief Gets existing hypotheses or algorithms
892  *  \param theDim - specifies dimension of returned hypotheses/algorifms
893  *  \param theHypType - specifies whether algorims or hypotheses or additional ones
894  *  are retrieved (possible values are in HypType enumeration)
895  *  \param theFather - start object for finding ( may be component, mesh, or sub-mesh )
896  *  \param theHyps - output list of names.
897  *  \param theHypVars - output list of variables.
898  *  \param theAlgoData - to select hypos able to be used by this algo (optional)
899  *
900  * Gets existing (i.e. already created) hypotheses or algorithm in accordance with
901  * input parameters.
902  *
903  * WARNING: when using this method to get hyps existing in Mesh component,
904  *          call availableHyps() before in order to get only hyps of available types
905  *          that was filtered by availableHyps()
906  */
907 //================================================================================
908 void SMESHGUI_MeshOp::existingHyps( const int       theDim,
909                                     const int       theHypType,
910                                     _PTR(SObject)   theFather,
911                                     QStringList&    theHyps,
912                                     THypList&       theHypList,
913                                     HypothesisData* theAlgoData) const
914 {
915   // Clear hypoheses list
916   theHyps.clear();
917   theHypList.clear();
918
919   if ( !theFather )
920     return;
921
922   _PTR(SObject)          aHypRoot;
923   _PTR(GenericAttribute) anAttr;
924   _PTR(AttributeName)    aName;
925   _PTR(AttributeIOR)     anIOR;
926
927   const bool isMesh = !_CAST( SComponent, theFather );
928   int aPart = -1;
929   if ( isMesh )
930     aPart = theHypType == Algo ? SMESH::Tag_RefOnAppliedAlgorithms : SMESH::Tag_RefOnAppliedHypothesis;
931   else
932     aPart = theHypType == Algo ? SMESH::Tag_AlgorithmsRoot : SMESH::Tag_HypothesisRoot;
933
934   const bool isAux   = ( theHypType >= AddHyp );
935   const bool allHyps = ( !isMesh && theHypType != Algo && theDim > -1);
936
937   if ( theFather->FindSubObject( aPart, aHypRoot ) )
938   {
939     _PTR(ChildIterator) anIter =
940       SMESH::GetActiveStudyDocument()->NewChildIterator( aHypRoot );
941     for ( ; anIter->More(); anIter->Next() )
942     {
943       _PTR(SObject) anObj = anIter->Value();
944       if ( isMesh ) // i.e. mesh or submesh
945       {
946         _PTR(SObject) aRefObj;
947         if ( anObj->ReferencedObject( aRefObj ) )
948           anObj = aRefObj;
949         else
950           continue;
951       }
952       if ( anObj->FindAttribute( anAttr, "AttributeName" ) )
953       {
954         aName = anAttr;
955         CORBA::Object_var aVar = _CAST(SObject,anObj)->GetObject();
956         if ( !CORBA::is_nil( aVar ) )
957         {
958           SMESH::SMESH_Hypothesis_var aHypVar = SMESH::SMESH_Hypothesis::_narrow( aVar );
959           if ( !aHypVar->_is_nil() )
960           {
961             CORBA::String_var hypType = aHypVar->GetName();
962             HypothesisData* aData = SMESH::GetHypothesisData( hypType.in() );
963             if ( !aData) continue;
964             if (( theDim == -1 || aData->Dim.contains( theDim ) ) &&
965                 ( isCompatible ( theAlgoData, aData, theHypType )) &&
966                 ( theHypType == Algo || isAux == aData->IsAuxOrNeedHyp ) &&
967                 ( !allHyps || myAvailableHypData[theDim][theHypType].count(aData) ))
968             {
969               std::string aHypName = aName->Value();
970               theHyps.append( aHypName.c_str() );
971               theHypList.append( THypItem( aHypVar, aHypName.c_str() ) );
972             }
973           }
974         }
975       }
976     }
977   }
978 }
979
980 //================================================================================
981 /*!
982  * \brief If create or edit a submesh, return a hypothesis holding parameters used
983  *        to mesh a sub-shape
984   * \param aHypType - The hypothesis type name
985   * \param aServerLib - Server library name
986   * \param hypData - The structure holding the hypothesis type etc.
987   * \retval SMESH::SMESH_Hypothesis_var - the hypothesis holding parameter values
988  */
989 //================================================================================
990 SMESH::SMESH_Hypothesis_var
991 SMESHGUI_MeshOp::getInitParamsHypothesis( const QString& aHypType,
992                                           const QString& aServerLib ) const
993 {
994   if ( aHypType.isEmpty() || aServerLib.isEmpty() )
995     return SMESH::SMESH_Hypothesis::_nil();
996
997   const int nbColonsInMeshEntry = 3;
998   bool isSubMesh = myToCreate ?
999     !myIsMesh :
1000     myDlg->selectedObject( SMESHGUI_MeshDlg::Obj ).count(':') > nbColonsInMeshEntry;
1001
1002   // get mesh and geom object
1003   SMESH::SMESH_Mesh_var aMeshVar = SMESH::SMESH_Mesh::_nil();
1004   GEOM::GEOM_Object_var aGeomVar = GEOM::GEOM_Object::_nil();
1005
1006   QString anEntry;
1007   if ( isSubMesh )
1008   {
1009     anEntry = myDlg->selectedObject
1010       ( myToCreate ? SMESHGUI_MeshDlg::Mesh : SMESHGUI_MeshDlg::Obj );
1011     if ( _PTR(SObject) pObj = studyDS()->FindObjectID( anEntry.toLatin1().data() ))
1012     {
1013       CORBA::Object_ptr Obj = _CAST( SObject,pObj )->GetObject();
1014       if ( myToCreate ) // mesh and geom may be selected
1015       {
1016         aMeshVar = SMESH::SMESH_Mesh::_narrow( Obj );
1017         anEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
1018         if ( _PTR(SObject) pGeom = studyDS()->FindObjectID( anEntry.toLatin1().data() ))
1019           aGeomVar= GEOM::GEOM_Object::_narrow( _CAST( SObject,pGeom )->GetObject() );
1020       }
1021       else // edition: sub-mesh may be selected
1022       {
1023         SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( Obj );
1024         if ( !sm->_is_nil() ) {
1025           aMeshVar = sm->GetFather();
1026           aGeomVar = sm->GetSubShape();
1027         }
1028       }
1029     }
1030   }
1031   else // mesh
1032   {
1033     if ( !myToCreate ) // mesh to edit can be selected
1034     {
1035       anEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
1036       if ( _PTR(SObject) pMesh = studyDS()->FindObjectID( anEntry.toLatin1().data() ))
1037       {
1038         aMeshVar = SMESH::SMESH_Mesh::_narrow( _CAST( SObject,pMesh )->GetObject() );
1039         if ( !aMeshVar->_is_nil() )
1040           aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pMesh );
1041       }
1042     }
1043     if ( aGeomVar->_is_nil() ) {
1044       anEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
1045       if ( _PTR(SObject) pGeom = studyDS()->FindObjectID( anEntry.toLatin1().data() ))
1046       {
1047         aGeomVar= GEOM::GEOM_Object::_narrow( _CAST( SObject,pGeom )->GetObject() );
1048       }
1049     }
1050   }
1051
1052   SMESH::SMESH_Hypothesis_var hyp =
1053     SMESHGUI::GetSMESHGen()->GetHypothesisParameterValues( aHypType.toLatin1().data(),
1054                                                            aServerLib.toLatin1().data(),
1055                                                            aMeshVar,
1056                                                            aGeomVar,
1057                                                            /*byMesh = */isSubMesh);
1058   if ( hyp->_is_nil() && isSubMesh )
1059     hyp = SMESHGUI::GetSMESHGen()->GetHypothesisParameterValues( aHypType.toLatin1().data(),
1060                                                                  aServerLib.toLatin1().data(),
1061                                                                  aMeshVar,
1062                                                                  aGeomVar,
1063                                                                  /*byMesh = */false);
1064   return hyp;
1065 }
1066
1067 //================================================================================
1068 /*!
1069  * \brief initialize a hypothesis creator
1070  */
1071 //================================================================================
1072
1073 void SMESHGUI_MeshOp::initHypCreator( SMESHGUI_GenericHypothesisCreator* theCreator )
1074 {
1075   if ( !theCreator ) return;
1076
1077   // Set shapes, of mesh and sub-mesh if any
1078
1079   // get Entry of the Geom object
1080   QString aGeomEntry = "";
1081   QString aMeshEntry = "";
1082   QString anObjEntry = "";
1083   aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
1084   aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
1085   anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
1086
1087   if ( myToCreate && myIsMesh )
1088     aMeshEntry = aGeomEntry;
1089
1090   if ( aMeshEntry != aGeomEntry ) { // Get Geom object from Mesh of a sub-mesh being edited
1091     _PTR(SObject) pObj = studyDS()->FindObjectID( aMeshEntry.toLatin1().data() );
1092     GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj );
1093     aMeshEntry = ( aGeomVar->_is_nil() ) ? QString() : SMESH::toQStr( aGeomVar->GetStudyEntry() );
1094   }
1095
1096   if ( aMeshEntry == "" && aGeomEntry == "" ) { // get geom of an object being edited
1097     _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() );
1098     bool isMesh;
1099     GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj, &isMesh );
1100     if ( !aGeomVar->_is_nil() )
1101     {
1102       aGeomEntry = SMESH::toQStr( aGeomVar->GetStudyEntry() );
1103       if ( isMesh )
1104         aMeshEntry = aGeomEntry;
1105     }
1106   }
1107
1108   if ( anObjEntry != "" && aGeomEntry != "" && aMeshEntry == "" ) {
1109     // take geometry from submesh being created
1110     _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() );
1111     if ( pObj ) {
1112       // if current object is sub-mesh
1113       SMESH::SMESH_subMesh_var aSubMeshVar =
1114         SMESH::SMESH_subMesh::_narrow( _CAST( SObject,pObj )->GetObject() );
1115       if ( !aSubMeshVar->_is_nil() ) {
1116         SMESH::SMESH_Mesh_var aMeshVar =  aSubMeshVar->GetFather();
1117         if ( !aMeshVar->_is_nil() ) {
1118           _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshVar );
1119           GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( aMeshSO );
1120           if ( !aGeomVar->_is_nil() )
1121             aMeshEntry = SMESH::toQStr( aGeomVar->GetStudyEntry() );
1122         }
1123       }
1124     }
1125   }
1126
1127   theCreator->setShapeEntry( aGeomEntry );
1128   if ( aMeshEntry != "" )
1129     theCreator->setMainShapeEntry( aMeshEntry );
1130 }
1131
1132 //================================================================================
1133 /*!
1134  * \Brief Returns tab dimention
1135   * \param tab - the tab in the dlg
1136   * \param dlg - my dialogue
1137   * \retval int - dimention
1138  */
1139 //================================================================================
1140 static int getTabDim (const QObject* tab, SMESHGUI_MeshDlg* dlg )
1141 {
1142   int aDim = -1;
1143   for (int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++)
1144     if (tab == dlg->tab(i))
1145       aDim = i;
1146   return aDim;
1147 }
1148
1149 //================================================================================
1150 /*!
1151  * \brief Create hypothesis
1152   * \param theHypType - hypothesis category (main or additional)
1153   * \param theIndex - index of type of hypothesis to be cerated
1154  *
1155  * Specifies dimension of hypothesis to be created (using sender() method),
1156  * specifies its type and calls method for hypothesis creation
1157  */
1158 //================================================================================
1159 void SMESHGUI_MeshOp::onCreateHyp( const int theHypType, const int theIndex )
1160 {
1161   // Specifies dimension of hypothesis to be created
1162   int aDim = getTabDim( sender(), myDlg );
1163   if (aDim == -1)
1164     return;
1165
1166   // Specifies type of hypothesis to be created
1167   THypDataList& dataList = myAvailableHypData[ aDim ][ theHypType ];
1168   if (theIndex < 0 || theIndex >= dataList.count())
1169     return;
1170   QString aHypTypeName = dataList[ theIndex ]->TypeName;
1171
1172   // Create hypothesis
1173   createHypothesis(aDim, theHypType, aHypTypeName);
1174 }
1175
1176 namespace
1177 {
1178   QString GetUniqueName (const QStringList& theHypNames,
1179                          const QString& theName,
1180                          size_t theIteration = 1)
1181   {
1182     QString aName = theName + "_" + QString::number( theIteration );
1183     if ( theHypNames.contains( aName ) )
1184       return GetUniqueName( theHypNames, theName, ++theIteration );
1185     return aName;
1186   }
1187 }
1188
1189 //================================================================================
1190 /*!
1191  *  Create hypothesis and update dialog.
1192  *  \param theDim - dimension of hypothesis to be created
1193  *  \param theType - hypothesis category (algorithm, hypothesis, additional hypothesis)
1194  *  \param theTypeName - specifies hypothesis to be created
1195  */
1196 //================================================================================
1197 void SMESHGUI_MeshOp::createHypothesis(const int theDim,
1198                                        const int theType,
1199                                        const QString& theTypeName)
1200 {
1201   HypothesisData* aData = SMESH::GetHypothesisData(theTypeName);
1202   if (!aData)
1203     return;
1204
1205   myDim = theDim;
1206   myType = theType;
1207
1208   // get a unique hyp name
1209   QStringList aHypNames;
1210   TDim2Type2HypList::const_iterator aDimIter = myExistingHyps.begin();
1211   for ( ; aDimIter != myExistingHyps.end(); aDimIter++) {
1212     const TType2HypList& aType2HypList = aDimIter.value();
1213     TType2HypList::const_iterator aTypeIter = aType2HypList.begin();
1214     for ( ; aTypeIter != aType2HypList.end(); aTypeIter++) {
1215       const THypList& aHypList = aTypeIter.value();
1216       THypList::const_iterator anIter = aHypList.begin();
1217       for ( ; anIter != aHypList.end(); anIter++) {
1218         const THypItem& aHypItem = *anIter;
1219         const QString& aHypName = aHypItem.second;
1220         aHypNames.append(aHypName);
1221       }
1222     }
1223   }
1224   QString aHypName = GetUniqueName( aHypNames, aData->Label);
1225
1226   // existing hypos
1227   bool dialog = false;
1228
1229   QString aClientLibName = aData->ClientLibName;
1230   if (aClientLibName == "") {
1231     // Call hypothesis creation server method (without GUI)
1232     SMESH::SMESH_Hypothesis_var aHyp =
1233       SMESH::CreateHypothesis(theTypeName, aHypName, false);
1234     aHyp.out();
1235   }
1236   else {
1237     // Get hypotheses creator client (GUI)
1238     SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(theTypeName);
1239
1240     // Create hypothesis
1241     if (aCreator)
1242     {
1243       // Get parameters appropriate to initialize a new hypothesis
1244       SMESH::SMESH_Hypothesis_var initParamHyp =
1245         getInitParamsHypothesis(theTypeName, aData->ServerLibName);
1246
1247       removeCustomFilters(); // Issue 0020170
1248
1249       // set shapes, of mesh and sub-mesh if any
1250       initHypCreator( aCreator );
1251
1252       myDlg->setEnabled( false );
1253       aCreator->create(initParamHyp, aHypName, myDlg, this, SLOT( onHypoCreated( int ) ) );
1254       dialog = true;
1255     }
1256     else {
1257      SMESH::SMESH_Hypothesis_var aHyp =
1258        SMESH::CreateHypothesis(theTypeName, aHypName, false);
1259      aHyp.out();
1260     }
1261   }
1262
1263   if( !dialog )
1264     onHypoCreated(2);
1265 }
1266
1267 //================================================================================
1268 /*!
1269  *  Necessary steps after hypothesis creation
1270  *  \param result - creation result:
1271  *   0 = rejected
1272  *   1 = accepted
1273  *   2 = additional value meaning that slot is called not from dialog box
1274  */
1275 //================================================================================
1276 void SMESHGUI_MeshOp::onHypoCreated( int result )
1277 {
1278   if( result != 2 )
1279   {
1280     int obj = myDlg->getActiveObject();
1281     onActivateObject( obj ); // Issue 0020170. Restore filters
1282     myDlg->setEnabled( true );
1283   }
1284
1285   _PTR(SComponent) aFather = SMESH::GetActiveStudyDocument()->FindComponent("SMESH");
1286
1287   int nbHyp = myExistingHyps[myDim][myType].count();
1288   HypothesisData* algoData = hypData( myDim, Algo, currentHyp( myDim, Algo ));
1289   QStringList aNewHyps;
1290   existingHyps(myDim, myType, aFather, aNewHyps, myExistingHyps[myDim][myType], algoData);
1291   if (aNewHyps.count() > nbHyp)
1292   {
1293     for (int i = nbHyp; i < aNewHyps.count(); i++)
1294       myDlg->tab(myDim)->addHyp(myType, aNewHyps[i]);
1295   }
1296
1297   if( result!=2 && myHypoSet )
1298     processSet();
1299 }
1300
1301 //================================================================================
1302 /*!
1303  * \brief Calls plugin methods for hypothesis editing
1304   * \param theHypType - specifies whether main hypothesis or additional one
1305   * is edited
1306   * \param theIndex - index of existing hypothesis
1307  *
1308  * Calls plugin methods for hypothesis editing
1309  */
1310 //================================================================================
1311 void SMESHGUI_MeshOp::onEditHyp( const int theHypType, const int theIndex )
1312 {
1313   // Speicfies dimension of hypothesis to be created
1314   int aDim = getTabDim( sender(), myDlg );
1315   if (aDim == -1)
1316     return;
1317
1318   const THypList& aList = myExistingHyps[ aDim ][ theHypType ];
1319   if ( theIndex < 0 || theIndex >= aList.count() )
1320     return;
1321   const THypItem& aHypItem = aList[ theIndex ];
1322   SMESH::SMESH_Hypothesis_var aHyp = aHypItem.first;
1323   if ( aHyp->_is_nil() )
1324     return;
1325
1326   SMESHGUI_GenericHypothesisCreator* aCreator =
1327     SMESH::GetHypothesisCreator( SMESH::toQStr( aHyp->GetName() ));
1328   if ( aCreator )
1329   {
1330     // set initial parameters
1331     SMESH::SMESH_Hypothesis_var initParamHyp =
1332       getInitParamsHypothesis( SMESH::toQStr( aHyp->GetName() ),
1333                                SMESH::toQStr( aHyp->GetLibName() ));
1334     aCreator->setInitParamsHypothesis( initParamHyp );
1335
1336     // set shapes, of mesh and sub-mesh if any
1337     initHypCreator( aCreator );
1338
1339     removeCustomFilters(); // Issue 0020170
1340     myDlg->setEnabled( false );
1341
1342     aCreator->edit( aHyp.in(), aHypItem.second, dlg(), this, SLOT( onHypoEdited( int ) ) );
1343   }
1344 }
1345
1346 //================================================================================
1347 /*!
1348  *  Necessary steps after hypothesis edition
1349  *  \param result - creation result:
1350  *   0 = rejected
1351  *   1 = accepted
1352  */
1353 //================================================================================
1354 void SMESHGUI_MeshOp::onHypoEdited( int result )
1355 {
1356   int obj = myDlg->getActiveObject();
1357   onActivateObject( obj ); // Issue 0020170. Restore filters
1358   myDlg->setEnabled( true );
1359 }
1360
1361 //================================================================================
1362 /*!
1363  * \brief access to hypothesis data
1364   * \param theDim - hyp dimension
1365   * \param theHypType - hyp type (Algo,MainHyp or AddHyp)
1366   * \param theIndex - index in the list
1367   * \retval HypothesisData* - result data, may be 0
1368  */
1369 //================================================================================
1370 HypothesisData* SMESHGUI_MeshOp::hypData( const int theDim,
1371                                           const int theHypType,
1372                                           const int theIndex)
1373 {
1374   if ( theDim     > -1 && theDim    <= SMESH::DIM_3D &&
1375        theHypType > -1 && theHypType < NbHypTypes &&
1376        theIndex   > -1 && theIndex   < myAvailableHypData[ theDim ][ theHypType ].count() )
1377     return myAvailableHypData[ theDim ][ theHypType ][ theIndex ];
1378   return 0;
1379 }
1380
1381 //================================================================================
1382 /*!
1383  * \brief Set available algos and hypos according to the selected algorithm
1384   * \param theIndex - algorithm index
1385  */
1386 //================================================================================
1387 void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
1388                                       const int theDim )
1389 {
1390   if ( myIgnoreAlgoSelection )
1391     return;
1392
1393   int aDim = theDim < 0 ? getTabDim( sender(), myDlg ): theDim;
1394   if (aDim == -1)
1395     return;
1396
1397   // find highest available dimension, all algos of this dimension are available for choice
1398   int aTopDim = -1;
1399   for (int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++)
1400     if (isAccessibleDim( i ))
1401       aTopDim = i;
1402   if (aTopDim == -1)
1403     return;
1404
1405   const bool isSubmesh = ( myToCreate ? !myIsMesh : myDlg->isObjectShown( SMESHGUI_MeshDlg::Mesh ));
1406
1407   HypothesisData* algoData = hypData( aDim, Algo, theIndex );
1408   HypothesisData* algoByDim[4];
1409   algoByDim[ aDim ] = algoData;
1410
1411   QStringList anAvailable;
1412
1413   // check that tab enabled of one less dimension
1414   if ( aDim > SMESH::DIM_0D )
1415   {
1416     if ( isAccessibleDim( aDim - 1 ) )
1417     {
1418       if (( myDlg->currentMeshType() != MT_ANY ) &&
1419           ( !algoData || ( myIsOnGeometry && algoData->InputTypes.isEmpty() )))
1420         for (int i = aDim - 1; i >= SMESH::DIM_0D; i--)
1421           if ( isAccessibleDim( i ) ) {
1422             myDlg->disableTab( i );
1423             setCurrentHyp(i, Algo, -1);
1424           }
1425     }
1426     else if ( algoData && myIsOnGeometry && !algoData->InputTypes.isEmpty() )
1427     {
1428       myDlg->enableTab( aDim - 1 );
1429     }
1430   }
1431
1432   // check that algorithms of other dimentions are compatible with
1433   // the selected one
1434   if ( !algoData ) { // all algos becomes available
1435     if (myDlg->currentMeshType() == MT_ANY || aDim == SMESH::DIM_1D || aDim == SMESH::DIM_0D)
1436       availableHyps( aDim, Algo, anAvailable, myAvailableHypData[ aDim ][ Algo ]);
1437     else{
1438       anAvailable.clear();
1439       for (int i = 0; i < myFilteredAlgoData[aDim].count(); ++i) {
1440         HypothesisData* aCurAlgo = myFilteredAlgoData[aDim][ i ];
1441         anAvailable.append( aCurAlgo->Label );
1442       }
1443     }
1444     myDlg->tab( aDim )->setAvailableHyps( Algo, anAvailable );
1445   }
1446   // 2 loops: backward and forward from algo dimension
1447   for ( int forward = false; forward <= true; ++forward )
1448   {
1449     int dim = aDim + 1, lastDim = SMESH::DIM_3D, dir = 1;
1450     if ( !forward ) {
1451       dim = aDim - 1; lastDim = SMESH::DIM_0D; dir = -1;
1452     }
1453     HypothesisData* prevAlgo = algoData;
1454     bool noCompatible = false;
1455     for ( ; dim * dir <= lastDim * dir; dim += dir)
1456     {
1457       if ( !isAccessibleDim( dim ))
1458         continue;
1459       if ( noCompatible ) { // the selected algo has no compatible ones
1460         anAvailable.clear();
1461         myDlg->tab( dim )->setAvailableHyps( Algo, anAvailable );
1462         myAvailableHypData[dim][Algo].clear();
1463         algoByDim[ dim ] = 0;
1464         continue;
1465       }
1466       // get currently selected algo
1467       int algoIndex = currentHyp( dim, Algo );
1468       HypothesisData* curAlgo = hypData( dim, Algo, algoIndex );
1469       if ( curAlgo ) { // some algo selected
1470         if ( !isCompatible( prevAlgo, curAlgo, Algo ))
1471           curAlgo = 0;
1472       }
1473       // set new available algoritms
1474       if (myDlg->currentMeshType() == MT_ANY || dim == SMESH::DIM_1D || dim == SMESH::DIM_0D)
1475         availableHyps( dim, Algo, anAvailable, myAvailableHypData[dim][Algo], prevAlgo );
1476       else{
1477         anAvailable.clear();
1478         myAvailableHypData[dim][Algo].clear();
1479         for (int i = 0; i < myFilteredAlgoData[dim].count(); ++i) {
1480           HypothesisData* aCurAlgo = myFilteredAlgoData[dim][ i ];
1481           if ( isCompatible ( prevAlgo, aCurAlgo, Algo )) {
1482             anAvailable.append( aCurAlgo->Label );
1483             myAvailableHypData[dim][Algo].append( aCurAlgo );
1484           }
1485         }
1486       }
1487       HypothesisData* soleCompatible = 0;
1488       if ( anAvailable.count() == 1 )
1489         soleCompatible = myAvailableHypData[dim][Algo][0];
1490       if ( dim == aTopDim && prevAlgo ) {// all available algoritms should be selectable any way
1491         if (myDlg->currentMeshType() == MT_ANY)
1492           availableHyps( dim, Algo, anAvailable, myAvailableHypData[dim][Algo], 0 );
1493       }
1494       myDlg->tab( dim )->setAvailableHyps( Algo, anAvailable );
1495       noCompatible = anAvailable.isEmpty();
1496
1497       // restore previously selected algo
1498       algoIndex = myAvailableHypData[dim][Algo].indexOf( curAlgo );
1499       if ( !isSubmesh && algoIndex < 0 && soleCompatible && !forward && dim != SMESH::DIM_0D)
1500         // select the sole compatible algo
1501         algoIndex = myAvailableHypData[dim][Algo].indexOf( soleCompatible );
1502       setCurrentHyp( dim, Algo, algoIndex);
1503
1504       // remember current algo
1505       prevAlgo = algoByDim[ dim ] = hypData( dim, Algo, algoIndex );
1506     }
1507   }
1508
1509   // set hypotheses corresponding to the found algoritms
1510
1511   _PTR(SObject) pObj = SMESH::GetActiveStudyDocument()->FindComponent("SMESH");
1512
1513   for ( int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++ )
1514   {
1515     if ( !isAccessibleDim( dim ))
1516       continue;
1517
1518     // get indices of selected hyps
1519     const int nbTypes = nbDlgHypTypes(dim);
1520     std::vector<int> hypIndexByType( nbTypes, -1 );
1521     for ( int dlgType = MainHyp; dlgType < nbTypes; dlgType++ )
1522     {
1523       hypIndexByType[ dlgType ] = currentHyp( dim, dlgType );
1524     }
1525
1526     // update hyps
1527     for ( int dlgType = MainHyp; dlgType < nbTypes; dlgType++ )
1528     {
1529       const int type = Min( dlgType, AddHyp );
1530       myAvailableHypData[ dim ][ type ].clear();
1531       QStringList anAvailable, anExisting;
1532
1533       HypothesisData* curAlgo = algoByDim[ dim ];
1534       int hypIndex = hypIndexByType[ dlgType ];
1535
1536       SMESH::SMESH_Hypothesis_var curHyp;
1537       if ( hypIndex >= 0 && hypIndex < myExistingHyps[ dim ][ type ].count() )
1538         curHyp = myExistingHyps[ dim ][ type ][ hypIndex ].first;
1539
1540       if ( !myToCreate && !curAlgo && !curHyp->_is_nil() ) { // edition, algo not selected
1541         // try to find algo by selected hypothesis in order to keep it selected
1542         bool algoDeselectedByUser = ( theDim < 0 && aDim == dim );
1543         QString curHypType = SMESH::toQStr( curHyp->GetName() );
1544         if ( !algoDeselectedByUser &&
1545              myObjHyps[ dim ][ type ].count() > 0 &&
1546              curHypType == SMESH::toQStr( myObjHyps[ dim ][ type ].first().first->GetName()) )
1547         {
1548           HypothesisData* hypData = SMESH::GetHypothesisData( curHyp->GetName() );
1549           for (int i = 0; i < myAvailableHypData[ dim ][ Algo ].count(); ++i) {
1550             curAlgo = myAvailableHypData[ dim ][ Algo ][ i ];
1551             if (curAlgo && hypData && isCompatible(curAlgo, hypData, type))
1552               break;
1553             else
1554               curAlgo = 0;
1555           }
1556         }
1557       }
1558       // get hyps compatible with curAlgo
1559       bool defaulHypAvlbl = false;
1560       if ( curAlgo )
1561       {
1562         // check if a selected hyp is compatible with the curAlgo
1563         if ( !curHyp->_is_nil() ) {
1564           HypothesisData* hypData = SMESH::GetHypothesisData( curHyp->GetName() );
1565           if ( !isCompatible( curAlgo, hypData, type ))
1566             curHyp = SMESH::SMESH_Hypothesis::_nil();
1567         }
1568         availableHyps( dim, type, anAvailable, myAvailableHypData[ dim ][ type ], curAlgo);
1569         existingHyps( dim, type, pObj, anExisting, myExistingHyps[ dim ][ type ], curAlgo);
1570         defaulHypAvlbl = (type == MainHyp && !curAlgo->IsAuxOrNeedHyp );
1571       }
1572       // set list of hypotheses
1573       if ( dlgType <= AddHyp )
1574       {
1575         myDlg->tab( dim )->setAvailableHyps( type, anAvailable );
1576         myDlg->tab( dim )->setExistingHyps( type, anExisting, defaulHypAvlbl );
1577       }
1578       // set current existing hypothesis
1579       if ( !curHyp->_is_nil() && !anExisting.isEmpty() )
1580         hypIndex = this->find( curHyp, myExistingHyps[ dim ][ type ]);
1581       else
1582         hypIndex = -1;
1583       if ( !isSubmesh && myToCreate && hypIndex < 0 && anExisting.count() == 1 ) {
1584         // none is yet selected => select the sole existing if it is not optional
1585         CORBA::String_var hypTypeName = myExistingHyps[ dim ][ type ].first().first->GetName();
1586         bool isOptional = true;
1587         if ( algoByDim[ dim ] &&
1588              SMESH::IsAvailableHypothesis( algoByDim[ dim ], hypTypeName.in(), isOptional ) &&
1589              !isOptional )
1590           hypIndex = 0;
1591       }
1592       setCurrentHyp( dim, dlgType, hypIndex );
1593     }
1594   }
1595 }
1596
1597 //================================================================================
1598 /*!
1599  * \brief Creates and selects hypothesis of hypotheses set
1600  * \param theSetName - The name of hypotheses set
1601  */
1602 //================================================================================
1603 void SMESHGUI_MeshOp::onHypoSet( const QString& theSetName )
1604 {
1605   myHypoSet = SMESH::GetHypothesesSet(theSetName);
1606   if (!myHypoSet)
1607     return;
1608
1609   // clear all hyps
1610   for (int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++) {
1611     setCurrentHyp(dim, Algo, -1);
1612     setCurrentHyp(dim, AddHyp, -1);
1613     setCurrentHyp(dim, MainHyp, -1);
1614   }
1615
1616   myHypoSet->init(true); //algorithms
1617   processSet();
1618   myHypoSet->init(false); //hypotheses
1619   processSet();
1620   myHypoSet = 0;
1621 }
1622
1623 //================================================================================
1624 /*!
1625  * \brief One step of hypothesis/algorithm list creation
1626  *
1627  * Creates a hypothesis or an algorithm for current item of internal list of names myHypoSet
1628  */
1629 //================================================================================
1630 void SMESHGUI_MeshOp::processSet()
1631 {
1632   myHypoSet->next();
1633   if( !myHypoSet->more() )
1634     return;
1635
1636   bool isAlgo = myHypoSet->isAlgo();
1637   QString aHypoTypeName = myHypoSet->current();
1638   HypothesisData* aHypData = SMESH::GetHypothesisData(aHypoTypeName);
1639   if (!aHypData)
1640   {
1641     processSet();
1642     return;
1643   }
1644
1645   int aDim = aHypData->Dim[0];
1646   // create or/and set
1647   if (isAlgo)
1648   {
1649     int index = myAvailableHypData[aDim][Algo].indexOf( aHypData );
1650     if ( index < 0 )
1651     {
1652       QStringList anAvailable;
1653       availableHyps( aDim, Algo, anAvailable, myAvailableHypData[aDim][Algo] );
1654       myDlg->tab( aDim )->setAvailableHyps( Algo, anAvailable );
1655       index = myAvailableHypData[aDim][Algo].indexOf( aHypData );
1656     }
1657     setCurrentHyp( aDim, Algo, index );
1658     onAlgoSelected( index, aDim );
1659     processSet();
1660   }
1661   else
1662   {
1663     bool mainHyp = true;
1664     QStringList anAvailable;
1665     availableHyps( aDim, MainHyp, anAvailable, myAvailableHypData[aDim][MainHyp] );
1666     myDlg->tab( aDim )->setAvailableHyps( MainHyp, anAvailable );
1667     int index = myAvailableHypData[aDim][MainHyp].indexOf( aHypData );
1668     if ( index < 0 )
1669     {
1670       mainHyp = false;
1671       index = myAvailableHypData[aDim][AddHyp].indexOf( aHypData );
1672     }
1673     if (index >= 0)
1674       createHypothesis(aDim, mainHyp ? MainHyp : AddHyp, aHypoTypeName);
1675     else
1676       processSet();
1677   }
1678 }
1679
1680 //================================================================================
1681 /*!
1682  * \brief Creates mesh
1683   * \param theMess - Output parameter intended for returning error message
1684   * \param theEntryList - List of entries of published objects
1685   * \retval bool  - TRUE if mesh is created, FALSE otherwise
1686  *
1687  * Creates mesh
1688  */
1689 //================================================================================
1690 bool SMESHGUI_MeshOp::createMesh( QString& theMess, QStringList& theEntryList )
1691 {
1692   theMess = "";
1693
1694   QStringList aList;
1695   myDlg->selectedObject( SMESHGUI_MeshDlg::Geom, aList );
1696   if ( aList.isEmpty() )
1697   {
1698     SMESH::SMESH_Gen_var aSMESHGen = SMESHGUI::GetSMESHGen();
1699     if ( aSMESHGen->_is_nil() )
1700       return false;
1701
1702     SMESH::SMESH_Mesh_var aMeshVar= aSMESHGen->CreateEmptyMesh();
1703     if ( aMeshVar->_is_nil() )
1704       return false;
1705
1706     _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshVar.in() );
1707     if ( aMeshSO ) {
1708       SMESH::SetName( aMeshSO, myDlg->objectText( SMESHGUI_MeshDlg::Obj ) );
1709       theEntryList.append( aMeshSO->GetID().c_str() );
1710     }
1711     return true;
1712   }
1713   QString namePrefix;
1714   if ( aList.count() > 1 )
1715   {
1716     namePrefix = myDlg->objectText( SMESHGUI_MeshDlg::Obj );
1717     int i = namePrefix.length() - 1;
1718     while ( i > 0 && namePrefix[i].isDigit() )
1719       --i;
1720     if ( i < namePrefix.length() - 1 )
1721       namePrefix.chop( namePrefix.length() - 1 - i );
1722     else
1723       namePrefix += "_";
1724   }
1725   QStringList::Iterator it = aList.begin();
1726   for ( int i = 0; it!=aList.end(); it++, ++i )
1727   {
1728     QString aGeomEntry = *it;
1729     _PTR(SObject) pGeom = studyDS()->FindObjectID( aGeomEntry.toLatin1().data() );
1730     GEOM::GEOM_Object_var aGeomVar =
1731       GEOM::GEOM_Object::_narrow( _CAST( SObject,pGeom )->GetObject() );
1732
1733     SMESH::SMESH_Gen_var aSMESHGen = SMESHGUI::GetSMESHGen();
1734     if ( aSMESHGen->_is_nil() )
1735       return false;
1736
1737     SUIT_OverrideCursor aWaitCursor;
1738
1739     // create mesh
1740     SMESH::SMESH_Mesh_var aMeshVar = aSMESHGen->CreateMesh( aGeomVar );
1741     if ( aMeshVar->_is_nil() )
1742       return false;
1743     _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshVar.in() );
1744     if ( aMeshSO ) {
1745       theEntryList.append( aMeshSO->GetID().c_str() );
1746       if ( i > 0 ) setDefaultName( namePrefix );
1747       SMESH::SetName( aMeshSO, myDlg->objectText( SMESHGUI_MeshDlg::Obj ) );
1748     }
1749
1750     for ( int aDim = SMESH::DIM_0D; aDim <= SMESH::DIM_3D; aDim++ )
1751     {
1752       if ( !isAccessibleDim( aDim )) continue;
1753
1754       // assign hypotheses
1755       for ( int dlgType = MainHyp; dlgType < nbDlgHypTypes(aDim); dlgType++ )
1756       {
1757         const int aHypIndex = currentHyp( aDim, dlgType );
1758         const int  aHypType = Min( dlgType, AddHyp );
1759         if ( aHypIndex >= 0 && aHypIndex < myExistingHyps[ aDim ][ aHypType ].count() )
1760         {
1761           SMESH::SMESH_Hypothesis_var aHypVar =
1762             myExistingHyps[ aDim ][ aHypType ][ aHypIndex ].first;
1763           if ( !aHypVar->_is_nil() )
1764             SMESH::AddHypothesisOnMesh( aMeshVar, aHypVar );
1765         }
1766       }
1767       // find or create algorithm
1768       SMESH::SMESH_Hypothesis_var anAlgoVar = getAlgo( aDim );
1769       if ( !anAlgoVar->_is_nil() )
1770         SMESH::AddHypothesisOnMesh( aMeshVar, anAlgoVar );
1771     }
1772   }
1773   return true;
1774 }
1775
1776 //================================================================================
1777 /*!
1778  * \brief Creates sub-mesh
1779   * \param theMess - Output parameter intended for returning error message
1780   * \param theEntryList - List of entries of published objects
1781   * \retval bool  - TRUE if sub-mesh is created, FALSE otherwise
1782  *
1783  * Creates sub-mesh
1784  */
1785 //================================================================================
1786 bool SMESHGUI_MeshOp::createSubMesh( QString& theMess, QStringList& theEntryList )
1787 {
1788   theMess = "";
1789
1790   SMESH::SMESH_Gen_var aSMESHGen = SMESHGUI::GetSMESHGen();
1791   if ( aSMESHGen->_is_nil() )
1792     return false;
1793
1794   // get mesh object
1795   QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
1796   _PTR(SObject) pMesh = studyDS()->FindObjectID( aMeshEntry.toLatin1().data() );
1797   SMESH::SMESH_Mesh_var aMeshVar =
1798     SMESH::SMESH_Mesh::_narrow( _CAST( SObject,pMesh )->GetObject() );
1799   if (aMeshVar->_is_nil())
1800     return false;
1801
1802   // GEOM shape of the main mesh
1803   GEOM::GEOM_Object_var mainGeom = aMeshVar->GetShapeToMesh();
1804
1805   // Name for the new sub-mesh
1806   QString aName = myDlg->objectText(SMESHGUI_MeshDlg::Obj);
1807
1808   // get geom object
1809   GEOM::GEOM_Object_var aGeomVar;
1810   QStringList aGEOMs;
1811   myDlg->selectedObject(SMESHGUI_MeshDlg::Geom, aGEOMs);
1812   if (aGEOMs.count() == 1)
1813   {
1814     //QString aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
1815     QString aGeomEntry = aGEOMs.first();
1816     _PTR(SObject) pGeom = studyDS()->FindObjectID( aGeomEntry.toLatin1().data() );
1817     aGeomVar = GEOM::GEOM_Object::_narrow( _CAST( SObject,pGeom )->GetObject() );
1818   }
1819   else if (aGEOMs.count() > 1)
1820   {
1821     // create a GEOM group
1822     GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen();
1823     _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
1824     if (!geomGen->_is_nil() && aStudy) {
1825       GEOM::GEOM_IGroupOperations_wrap op =
1826         geomGen->GetIGroupOperations(aStudy->StudyId());
1827       if (!op->_is_nil()) {
1828         // check and add all selected GEOM objects: they must be
1829         // a sub-shapes of the main GEOM and must be of one type
1830         int iSubSh = 0;
1831         TopAbs_ShapeEnum aGroupType = TopAbs_SHAPE;
1832         GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO;
1833         aSeq->length(aGEOMs.count());
1834         QStringList::const_iterator aSubShapesIter = aGEOMs.begin();
1835         for ( ; aSubShapesIter != aGEOMs.end(); aSubShapesIter++, iSubSh++) {
1836           QString aSubGeomEntry = (*aSubShapesIter);
1837           _PTR(SObject) pSubGeom = studyDS()->FindObjectID(aSubGeomEntry.toLatin1().data());
1838           GEOM::GEOM_Object_var aSubGeomVar =
1839             GEOM::GEOM_Object::_narrow(_CAST(SObject,pSubGeom)->GetObject());
1840           TopAbs_ShapeEnum aSubShapeType = (TopAbs_ShapeEnum)aSubGeomVar->GetShapeType();
1841           if (iSubSh == 0) {
1842             aGroupType = aSubShapeType;
1843           } else {
1844             if (aSubShapeType != aGroupType)
1845               aGroupType = TopAbs_SHAPE;
1846           }
1847           aSeq[iSubSh] = aSubGeomVar;
1848         }
1849         // create a group
1850         GEOM::GEOM_Object_wrap aGroupVar = op->CreateGroup(mainGeom, aGroupType);
1851         op->UnionList(aGroupVar, aSeq);
1852
1853         if (op->IsDone())
1854         {
1855           aGeomVar = GEOM::GEOM_Object::_duplicate( aGroupVar.in() );
1856
1857           // publish the GEOM group in study
1858           QString aNewGeomGroupName ("Auto_group_for_");
1859           aNewGeomGroupName += aName;
1860           SALOMEDS::Study_var aStudyVar = _CAST(Study, aStudy)->GetStudy();
1861           SALOMEDS::SObject_wrap aNewGroupSO =
1862             geomGen->AddInStudy( aStudyVar, aGeomVar,
1863                                  aNewGeomGroupName.toLatin1().data(), mainGeom);
1864         }
1865       }
1866     }
1867   }
1868   else {
1869   }
1870   if (aGeomVar->_is_nil())
1871     return false;
1872
1873   SUIT_OverrideCursor aWaitCursor;
1874
1875   // create sub-mesh
1876   SMESH::SMESH_subMesh_var aSubMeshVar = aMeshVar->GetSubMesh( aGeomVar, aName.toLatin1().data() );
1877   _PTR(SObject) aSubMeshSO = SMESH::FindSObject( aSubMeshVar.in() );
1878   if ( aSubMeshSO ) {
1879     SMESH::SetName( aSubMeshSO, aName.toLatin1().data() );
1880     theEntryList.append( aSubMeshSO->GetID().c_str() );
1881   }
1882
1883   for ( int aDim = SMESH::DIM_0D; aDim <= SMESH::DIM_3D; aDim++ )
1884   {
1885     if ( !isAccessibleDim( aDim )) continue;
1886
1887     // find or create algorithm
1888     SMESH::SMESH_Hypothesis_var anAlgoVar = getAlgo( aDim );
1889     if ( !anAlgoVar->_is_nil() )
1890       SMESH::AddHypothesisOnSubMesh( aSubMeshVar, anAlgoVar );
1891     // assign hypotheses
1892     for ( int dlgType = MainHyp; dlgType < nbDlgHypTypes(aDim); dlgType++ )
1893     {
1894       const int aHypIndex = currentHyp( aDim, dlgType );
1895       const int  aHypType = Min( dlgType, AddHyp );
1896       if ( aHypIndex >= 0 && aHypIndex < myExistingHyps[ aDim ][ aHypType ].count() )
1897       {
1898         SMESH::SMESH_Hypothesis_var aHypVar =
1899           myExistingHyps[ aDim ][ aHypType ][ aHypIndex ].first;
1900         if ( !aHypVar->_is_nil() )
1901           SMESH::AddHypothesisOnSubMesh( aSubMeshVar, aHypVar );
1902       }
1903     }
1904   }
1905
1906   // deselect geometry: next submesh should be created on other sub-shape
1907   myDlg->clearSelection( SMESHGUI_MeshDlg::Geom );
1908   selectObject( _PTR(SObject)() );
1909   selectionDone();
1910
1911   checkSubMeshConcurrency( aMeshVar, aSubMeshVar, /*askUser=*/true );
1912
1913   return true;
1914 }
1915
1916 //================================================================================
1917 /*!
1918  * \brief Gets current hypothesis or algorithms
1919   * \param theDim - dimension of hypothesis or algorithm
1920   * \param theHypType - Type of hypothesis (Algo, MainHyp, AddHyp)
1921   * \retval int - current hypothesis or algorithms
1922  *
1923  * Gets current hypothesis or algorithms
1924  */
1925 //================================================================================
1926 int SMESHGUI_MeshOp::currentHyp( const int theDim, const int theHypType ) const
1927 {
1928   return myDlg->tab( theDim )->currentHyp( theHypType ) - 1;
1929 }
1930
1931 //================================================================================
1932 /*!
1933  * \brief Checks if a hypothesis is selected
1934  */
1935 //================================================================================
1936
1937 bool SMESHGUI_MeshOp::isSelectedHyp( int theDim, int theHypType, int theIndex) const
1938 {
1939   if ( theHypType < AddHyp ) // only one hyp can be selected
1940     return currentHyp( theDim, theHypType ) == theIndex;
1941
1942   for ( int dlgHypType = AddHyp; dlgHypType < nbDlgHypTypes( theDim ); ++dlgHypType )
1943     if ( currentHyp( theDim, dlgHypType ) == theIndex )
1944       return true;
1945
1946   return false;
1947 }
1948
1949 //================================================================================
1950 /*!
1951  * \brief Returns nb of HypType's taking into account possible several
1952  *        selected additional hypotheses which are coded as additional HypType's.
1953  */
1954 //================================================================================
1955
1956 int SMESHGUI_MeshOp::nbDlgHypTypes( const int dim ) const
1957 {
1958   return NbHypTypes + myDlg->tab( dim )->nbAddHypTypes();
1959 }
1960
1961 //================================================================================
1962 /*!
1963  * \brief Returns true if hypotheses of given dim can be assigned
1964   * \param theDim - hypotheses dimension
1965   * \retval bool - result
1966  */
1967 //================================================================================
1968 bool SMESHGUI_MeshOp::isAccessibleDim( const int theDim ) const
1969 {
1970   return myDlg->isTabEnabled( theDim );
1971 }
1972
1973 //================================================================================
1974 /*!
1975  * \brief Sets current hypothesis or algorithms
1976   * \param theDim - dimension of hypothesis or algorithm
1977   * \param theHypType - Type of hypothesis (Algo, MainHyp, AddHyp)
1978   * \param theIndex - Index of hypothesis
1979  *
1980  * Gets current hypothesis or algorithms
1981  */
1982 //================================================================================
1983 void SMESHGUI_MeshOp::setCurrentHyp( const int theDim,
1984                                      const int theHypType,
1985                                      const int theIndex )
1986 {
1987   myIgnoreAlgoSelection = true;
1988   myDlg->tab( theDim )->setCurrentHyp( theHypType, theIndex + 1 );
1989   myIgnoreAlgoSelection = false;
1990 }
1991
1992 //================================================================================
1993 /*!
1994  * \brief Generates default and sets mesh/submesh name
1995  *
1996  * Generates and sets default mesh/submesh name(Mesh_1, Mesh_2, etc.)
1997  */
1998 //================================================================================
1999 void SMESHGUI_MeshOp::setDefaultName( const QString& thePrefix ) const
2000 {
2001   QString aResName;
2002
2003   _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
2004   int i = 1;
2005
2006   QString aPrefix = thePrefix;
2007   if ( aPrefix.isEmpty() )
2008     aPrefix = tr( myIsMesh ? "SMESH_OBJECT_MESH" : "SMESH_SUBMESH" ) + "_";
2009
2010   _PTR(SObject) anObj;
2011   do
2012   {
2013     aResName = aPrefix + QString::number( i++ );
2014     anObj = aStudy->FindObject( aResName.toLatin1().data() );
2015   }
2016   while ( anObj );
2017
2018   QLineEdit* aControl = ( QLineEdit* )myDlg->objectWg(
2019     SMESHGUI_MeshDlg::Obj, SMESHGUI_MeshDlg::Control );
2020   aControl->setText( aResName );
2021 }
2022
2023 //================================================================================
2024 /*!
2025  * \brief Gets algorithm or creates it if necessary
2026   * \param theDim - specifies dimension of returned hypotheses/algorifms
2027   * \retval SMESH::SMESH_Hypothesis_var - algorithm
2028  *
2029  * Gets algorithm or creates it if necessary
2030  */
2031 //================================================================================
2032 SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim )
2033 {
2034   SMESH::SMESH_Hypothesis_var anAlgoVar;
2035
2036   // get type of the selected algo
2037   int aHypIndex = currentHyp( theDim, Algo );
2038   THypDataList& dataList = myAvailableHypData[ theDim ][ Algo ];
2039   if ( aHypIndex < 0 || aHypIndex >= dataList.count())
2040     return anAlgoVar;
2041   QString aHypName = dataList[ aHypIndex ]->TypeName;
2042
2043   // get existing algoritms
2044   _PTR(SObject) pObj = SMESH::GetActiveStudyDocument()->FindComponent("SMESH");
2045   QStringList tmp;
2046   existingHyps( theDim, Algo, pObj, tmp, myExistingHyps[ theDim ][ Algo ]);
2047
2048   // look for an existing algo of such a type
2049   THypList& aHypVarList = myExistingHyps[ theDim ][ Algo ];
2050   THypList::iterator anIter = aHypVarList.begin();
2051   for ( ; anIter != aHypVarList.end(); anIter++)
2052   {
2053     SMESH::SMESH_Hypothesis_var aHypVar = (*anIter).first;
2054     if ( !aHypVar->_is_nil() && aHypName == SMESH::toQStr( aHypVar->GetName() ))
2055     {
2056       anAlgoVar = aHypVar;
2057       break;
2058     }
2059   }
2060
2061   if (anAlgoVar->_is_nil())
2062   {
2063     HypothesisData* aHypData = SMESH::GetHypothesisData( aHypName );
2064     if (aHypData)
2065     {
2066       QString aClientLibName = aHypData->ClientLibName;
2067       if ( aClientLibName.isEmpty() )
2068       {
2069         // Call hypothesis creation server method (without GUI)
2070         SMESH::SMESH_Hypothesis_var aHyp =
2071           SMESH::CreateHypothesis(aHypName, aHypName, true);
2072         aHyp.out();
2073       }
2074       else
2075       {
2076         // Get hypotheses creator client (GUI)
2077         SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(aHypName);
2078
2079         // Create algorithm
2080         if (aCreator)
2081           aCreator->create( true, aHypName, myDlg, 0, QString::null );
2082         else {
2083           SMESH::SMESH_Hypothesis_var aHyp =
2084             SMESH::CreateHypothesis(aHypName, aHypName, true);
2085           aHyp.out();
2086         }
2087       }
2088       QStringList tmpList;
2089       _PTR(SComponent) aFather = SMESH::GetActiveStudyDocument()->FindComponent( "SMESH" );
2090       existingHyps( theDim, Algo, aFather, tmpList, myExistingHyps[ theDim ][ Algo ] );
2091     }
2092
2093     THypList& aNewHypVarList = myExistingHyps[ theDim ][ Algo ];
2094     for ( anIter = aNewHypVarList.begin(); anIter != aNewHypVarList.end(); ++anIter )
2095     {
2096       SMESH::SMESH_Hypothesis_var aHypVar = (*anIter).first;
2097       if ( !aHypVar->_is_nil() && aHypName == SMESH::toQStr( aHypVar->GetName() ))
2098       {
2099         anAlgoVar = aHypVar;
2100         break;
2101       }
2102     }
2103   }
2104
2105   return anAlgoVar._retn();
2106 }
2107
2108 //================================================================================
2109 /*!
2110  * \brief Reads parameters of an edited mesh/sub-mesh and assigns them to the dialog
2111  *
2112  * Called when mesh is edited only.
2113  */
2114 //================================================================================
2115 void SMESHGUI_MeshOp::readMesh()
2116 {
2117   QString anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
2118   _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() );
2119   if ( !pObj )
2120     return;
2121
2122   if (myIsOnGeometry) {
2123     // Get name of mesh if current object is sub-mesh
2124     SMESH::SMESH_subMesh_var aSubMeshVar =
2125       SMESH::SMESH_subMesh::_narrow( _CAST( SObject,pObj )->GetObject() );
2126     if ( !aSubMeshVar->_is_nil() )
2127     {
2128       SMESH::SMESH_Mesh_var aMeshVar =  aSubMeshVar->GetFather();
2129       if ( !aMeshVar->_is_nil() )
2130       {
2131         _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshVar );
2132         QString aMeshName = name( aMeshSO );
2133         myDlg->setObjectText( SMESHGUI_MeshDlg::Mesh, aMeshName );
2134       }
2135       myHasConcurrentSubBefore = checkSubMeshConcurrency( aMeshVar, aSubMeshVar );
2136     }
2137
2138     // Get name of geometry object
2139     CORBA::String_var name = SMESH::GetGeomName( pObj );
2140     if ( name.in() )
2141       myDlg->setObjectText( SMESHGUI_MeshDlg::Geom, name.in() );
2142   }
2143
2144   // Get hypotheses and algorithms assigned to the mesh/sub-mesh
2145   QStringList anExisting;
2146   const int lastDim = ( myIsOnGeometry ) ? SMESH::DIM_0D : SMESH::DIM_3D;
2147   bool algoFound = false;
2148   for ( int dim = SMESH::DIM_3D; dim >= lastDim; --dim )
2149   {
2150     // get algorithm
2151     existingHyps( dim, Algo, pObj, anExisting, myObjHyps[ dim ][ Algo ] );
2152     // find algo index among available ones
2153     int aHypIndex = -1;
2154     if ( myObjHyps[ dim ][ Algo ].count() > 0 )
2155     {
2156       SMESH::SMESH_Hypothesis_var aVar = myObjHyps[ dim ][ Algo ].first().first;
2157       HypothesisData* algoData = SMESH::GetHypothesisData( aVar->GetName() );
2158       aHypIndex = myAvailableHypData[ dim ][ Algo ].indexOf ( algoData );
2159       //       if ( aHypIndex < 0 && algoData ) {
2160       //         // assigned algo is incompatible with other algorithms
2161       //         myAvailableHypData[ dim ][ Algo ].push_back( algoData );
2162       //         aHypIndex = myAvailableHypData[ dim ][ hypType ].count() - 1;
2163       //       }
2164       algoFound = ( aHypIndex > -1 );
2165     }
2166     setCurrentHyp( dim, Algo, aHypIndex );
2167     // set existing and available hypothesis according to the selected algo
2168     if ( aHypIndex > -1 || !algoFound )
2169       onAlgoSelected( aHypIndex, dim );
2170   }
2171
2172   // get hypotheses
2173   bool hypWithoutAlgo = false;
2174   for ( int dim = SMESH::DIM_3D; dim >= lastDim; --dim )
2175   {
2176     for ( int hypType = MainHyp; hypType <= AddHyp; hypType++ )
2177     {
2178       // get hypotheses
2179       existingHyps( dim, hypType, pObj, anExisting, myObjHyps[ dim ][ hypType ] );
2180       for ( int i = 0, nb = myObjHyps[ dim ][ hypType ].count(); i < nb; ++i )
2181       {
2182         // find index of required hypothesis among existing ones for this dimension and type
2183         int aHypIndex = find( myObjHyps[ dim ][ hypType ][ i ].first,
2184                               myExistingHyps[ dim ][ hypType ] );
2185         if ( aHypIndex < 0 ) {
2186           // assigned hypothesis is incompatible with the algorithm
2187           if ( currentHyp( dim, Algo ) < 0 )
2188           { // none algo selected; it is edition for sure, of submesh maybe
2189             hypWithoutAlgo = true;
2190             myExistingHyps[ dim ][ hypType ].push_back( myObjHyps[ dim ][ hypType ][ i ] );
2191             anExisting.push_back( myObjHyps[ dim ][ hypType ][ i ].second );
2192             aHypIndex = myExistingHyps[ dim ][ hypType ].count() - 1;
2193             myDlg->tab( dim )->setExistingHyps( hypType, anExisting );
2194           }
2195         }
2196         setCurrentHyp( dim, hypType + i, aHypIndex );
2197
2198         if ( hypType == MainHyp ) break; // only one main hyp allowed
2199       }
2200     }
2201   }
2202   // make available other hyps of same type as one without algo
2203   if ( hypWithoutAlgo )
2204     onAlgoSelected( currentHyp( 0, Algo ), 0 );
2205 }
2206
2207 //================================================================================
2208 /*!
2209  * \brief Gets name of object
2210  * \param theSO - SObject
2211  * \retval QString - name of object
2212  *
2213  * Gets name of object
2214  */
2215 //================================================================================
2216 QString SMESHGUI_MeshOp::name( _PTR(SObject) theSO ) const
2217 {
2218   QString aResName;
2219   if ( theSO )
2220   {
2221     _PTR(GenericAttribute) anAttr;
2222     _PTR(AttributeName)    aNameAttr;
2223     if ( theSO->FindAttribute( anAttr, "AttributeName" ) )
2224     {
2225       aNameAttr = anAttr;
2226       aResName = aNameAttr->Value().c_str();
2227     }
2228   }
2229   return aResName;
2230 }
2231
2232 //================================================================================
2233 /*!
2234  * \brief Finds hypothesis in input list
2235   * \param theHyp - hypothesis to be found
2236   * \param theHypList - input list of hypotheses
2237   * \retval int - index of hypothesis or -1 if it is not found
2238  *
2239  * Finds position of hypothesis in input list
2240  */
2241 //================================================================================
2242 int SMESHGUI_MeshOp::find( const SMESH::SMESH_Hypothesis_var& theHyp,
2243                            const THypList& theHypList ) const
2244 {
2245   int aRes = -1;
2246   if ( !theHyp->_is_nil() )
2247   {
2248     int i = 0;
2249     THypList::const_iterator anIter = theHypList.begin();
2250     for ( ; anIter != theHypList.end(); ++ anIter)
2251     {
2252       if ( theHyp->_is_equivalent( (*anIter).first ) )
2253       {
2254         aRes = i;
2255         break;
2256       }
2257       i++;
2258     }
2259   }
2260   return aRes;
2261 }
2262
2263 //================================================================================
2264 /*!
2265  * \brief Edits mesh or sub-mesh
2266   * \param theMess - Output parameter intended for returning error message
2267   * \retval bool  - TRUE if mesh is edited succesfully, FALSE otherwise
2268  *
2269  * Assigns new name hypotheses and algoriths to the mesh or sub-mesh
2270  */
2271 //================================================================================
2272 bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess )
2273 {
2274   theMess = "";
2275
2276   SMESH::SMESH_Gen_var aSMESHGen = SMESHGUI::GetSMESHGen();
2277   if ( aSMESHGen->_is_nil() )
2278     return false;
2279
2280   QString anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
2281   _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() );
2282   if ( !pObj )
2283     return false;
2284
2285   SUIT_OverrideCursor aWaitCursor;
2286
2287   // Set new name
2288   QString aName = myDlg->objectText( SMESHGUI_MeshDlg::Obj );
2289   SMESH::SetName( pObj, aName );
2290   int aDim = ( myIsOnGeometry ) ? SMESH::DIM_0D : SMESH::DIM_3D;
2291
2292   // First, remove old algos in order to avoid messages on algorithm hiding
2293   for ( int dim = aDim; dim <= SMESH::DIM_3D; dim++ )
2294   {
2295     if ( isAccessibleDim( dim ) && myObjHyps[ dim ][ Algo ].count() > 0 )
2296     {
2297       SMESH::SMESH_Hypothesis_var anOldAlgo = myObjHyps[ dim ][ Algo ].first().first;
2298       SMESH::SMESH_Hypothesis_var anAlgoVar = getAlgo( dim );
2299       if ( anAlgoVar->_is_nil() || // no new algo selected or
2300            strcmp(anOldAlgo->GetName(), anAlgoVar->GetName()) ) // algo change
2301       {
2302         // remove old algorithm
2303         SMESH::RemoveHypothesisOrAlgorithmOnMesh ( pObj, myObjHyps[ dim ][ Algo ].first().first );
2304         myObjHyps[ dim ][ Algo ].clear();
2305       }
2306     }
2307   }
2308
2309   SALOMEDS_SObject* aSObject = _CAST(SObject, pObj);
2310   CORBA::Object_var anObject = aSObject->GetObject();
2311   SMESH::SMESH_Mesh_var       aMeshVar = SMESH::SMESH_Mesh::_narrow( anObject );
2312   SMESH::SMESH_subMesh_var aSubMeshVar = SMESH::SMESH_subMesh::_narrow( anObject );
2313   bool isMesh = !aMeshVar->_is_nil();
2314   if ( !isMesh && !aSubMeshVar->_is_nil() )
2315     aMeshVar = aSubMeshVar->GetFather();
2316
2317   // Assign new algorithms and hypotheses
2318   for ( int dim = aDim; dim <= SMESH::DIM_3D; dim++ )
2319   {
2320     if ( !isAccessibleDim( dim )) continue;
2321
2322     // find or create algorithm
2323     SMESH::SMESH_Hypothesis_var anAlgoVar = getAlgo( dim );
2324
2325     // assign new algorithm
2326     if ( !anAlgoVar->_is_nil() && // some algo selected and
2327          myObjHyps[ dim ][ Algo ].count() == 0 ) // no algo assigned
2328     {
2329       if ( isMesh )
2330         SMESH::AddHypothesisOnMesh( aMeshVar, anAlgoVar );
2331       else if ( !aSubMeshVar->_is_nil() )
2332         SMESH::AddHypothesisOnSubMesh( aSubMeshVar, anAlgoVar );
2333
2334       myObjHyps[ dim ][ Algo ].append( THypItem( anAlgoVar, aName) );
2335     }
2336
2337     // remove deselected hypotheses
2338     for ( int hypType = MainHyp; hypType <= AddHyp; hypType++ )
2339     {
2340       for ( int i = 0, nb = myObjHyps[ dim ][ hypType ].count(); i < nb; ++i )
2341       {
2342         SMESH::SMESH_Hypothesis_var hyp = myObjHyps[ dim ][ hypType ][ i ].first;
2343         int hypIndex = this->find( hyp, myExistingHyps[ dim ][ hypType ]);
2344         if ( !isSelectedHyp( dim, hypType, hypIndex ) && !hyp->_is_nil() )
2345         {
2346           SMESH::RemoveHypothesisOrAlgorithmOnMesh( pObj, hyp );
2347         }
2348       }
2349     }
2350     // assign newly selected hypotheses
2351     for ( int dlgType = MainHyp; dlgType < nbDlgHypTypes(dim); dlgType++ )
2352     {
2353       const int curIndex = currentHyp( dim, dlgType );
2354       const int  hypType = Min( dlgType, AddHyp );
2355       if ( curIndex >= 0 && curIndex < myExistingHyps[ dim ][ hypType ].count() )
2356       {
2357         SMESH::SMESH_Hypothesis_var hyp = myExistingHyps[ dim ][ hypType ][ curIndex ].first;
2358
2359         bool isAssigned = ( this->find( hyp, myObjHyps[ dim ][ hypType ]) >= 0 );
2360         if ( !isAssigned )
2361         {
2362           if ( isMesh )
2363             SMESH::AddHypothesisOnMesh (aMeshVar, hyp );
2364           else if ( !aSubMeshVar->_is_nil() )
2365             SMESH::AddHypothesisOnSubMesh ( aSubMeshVar, hyp );
2366         }
2367       }
2368       // reread all hypotheses of mesh
2369       QStringList anExisting;
2370       existingHyps( dim, hypType, pObj, anExisting, myObjHyps[ dim ][ hypType ] );
2371     }
2372   }
2373
2374   myHasConcurrentSubBefore =
2375     checkSubMeshConcurrency( aMeshVar, aSubMeshVar, /*askUser=*/!myHasConcurrentSubBefore );
2376
2377   return true;
2378 }
2379
2380 //================================================================================
2381 /*!
2382  * \brief Checks if a concurrent sub-meshes appear as result of sub-mesh
2383  *        creation/edition and, if (askUser) , proposes the uses to set up a desired
2384  *        order of sub-mesh computation.
2385  *        Returns \c true if a sub-mesh concurrency detected.
2386  */
2387 //================================================================================
2388
2389 bool SMESHGUI_MeshOp::checkSubMeshConcurrency(SMESH::SMESH_Mesh_ptr    mesh,
2390                                               SMESH::SMESH_subMesh_ptr submesh,
2391                                               bool                     askUser)
2392 {
2393   if ( CORBA::is_nil( mesh ) || CORBA::is_nil( submesh ))
2394     return false;
2395
2396   bool isNewConcurrent = mesh->IsUnorderedSubMesh( submesh->GetId() );
2397   if ( isNewConcurrent && askUser )
2398   {
2399     int butID = SUIT_MessageBox::warning( myDlg->parentWidget(), tr( "SMESH_WARNING" ),
2400                                           tr("CONCURRENT_SUBMESH_APPEARS"),
2401                                           tr("SMESH_BUT_YES"), tr("SMESH_BUT_NO"));
2402     if ( butID == 0 )
2403     {
2404       _PTR(SObject) meshSO = SMESH::FindSObject( mesh );
2405       LightApp_SelectionMgr* aSelectionMgr = selectionMgr();
2406       if ( meshSO && aSelectionMgr )
2407       {
2408         myDlg->setEnabled( false ); // disactivate selection
2409         selectionMgr()->clearFilters();
2410         selectObject( meshSO );
2411         SMESHGUI::GetSMESHGUI()->OnGUIEvent( SMESHOp::OpMeshOrder ); // MESH_ORDER
2412         qApp->processEvents();
2413
2414         myDlg->setEnabled( true );
2415         int obj = myDlg->getActiveObject();
2416         onActivateObject( obj ); // restore filter
2417         if ( !myToCreate )
2418         {
2419           selectObject( SMESH::FindSObject( submesh ));
2420           selectionDone();
2421         }
2422       }
2423     }
2424   }
2425
2426   return isNewConcurrent;
2427 }
2428
2429 //================================================================================
2430 /*!
2431  * \brief Verifies whether given operator is valid for this one
2432  * \param theOtherOp - other operation
2433  * \return Returns TRUE if the given operator is valid for this one, FALSE otherwise
2434  *
2435  * method redefined from base class verifies whether given operator is valid for
2436  * this one (i.e. can be started "above" this operator). In current implementation method
2437  * retuns false if theOtherOp operation is not intended for deleting objects or mesh
2438  * elements.
2439  */
2440 //================================================================================
2441 bool SMESHGUI_MeshOp::isValid( SUIT_Operation* theOp ) const
2442 {
2443   return SMESHGUI_Operation::isValid( theOp ) && !theOp->inherits( "SMESHGUI_MeshOp" );
2444 }
2445
2446 //================================================================================
2447 /*!
2448  * \brief SLOT. Is called when the user selects a way of geometry selection
2449  * \param theByMesh - true if the user wants to find geometry by mesh element
2450  */
2451 //================================================================================
2452 void SMESHGUI_MeshOp::onGeomSelectionByMesh( bool theByMesh )
2453 {
2454   if ( theByMesh ) {
2455     if ( !myShapeByMeshOp ) {
2456       myShapeByMeshOp = new SMESHGUI_ShapeByMeshOp();
2457       connect(myShapeByMeshOp, SIGNAL(committed(SUIT_Operation*)),
2458               SLOT(onPublishShapeByMeshDlg(SUIT_Operation*)));
2459       connect(myShapeByMeshOp, SIGNAL(aborted(SUIT_Operation*)),
2460               SLOT(onCloseShapeByMeshDlg(SUIT_Operation*)));
2461     }
2462     // set mesh object to SMESHGUI_ShapeByMeshOp and start it
2463     QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
2464     if ( _PTR(SObject) pMesh = studyDS()->FindObjectID( aMeshEntry.toLatin1().data() )) {
2465       SMESH::SMESH_Mesh_var aMeshVar =
2466         SMESH::SMESH_Mesh::_narrow( _CAST( SObject,pMesh )->GetObject() );
2467       if ( !aMeshVar->_is_nil() ) {
2468         myDlg->hide(); // stop processing selection
2469         myShapeByMeshOp->setModule( getSMESHGUI() );
2470         myShapeByMeshOp->setStudy( 0 ); // it's really necessary
2471         myShapeByMeshOp->SetMesh( aMeshVar );
2472         myShapeByMeshOp->start();
2473       }
2474     }
2475   }
2476 }
2477
2478 //================================================================================
2479 /*!
2480  * \brief SLOT. Is called when Ok is pressed in SMESHGUI_ShapeByMeshDlg
2481  */
2482 //================================================================================
2483 void SMESHGUI_MeshOp::onPublishShapeByMeshDlg(SUIT_Operation* op)
2484 {
2485   if ( myShapeByMeshOp == op ) {
2486     SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser(); //MZN: 24.11.2006  IPAL13980 - Object Browser update added
2487     myDlg->show();
2488     // Select a found geometry object
2489     GEOM::GEOM_Object_var aGeomVar = myShapeByMeshOp->GetShape();
2490     if ( !aGeomVar->_is_nil() )
2491     {
2492       QString ID = SMESH::toQStr( aGeomVar->GetStudyEntry() );
2493       if ( _PTR(SObject) aGeomSO = studyDS()->FindObjectID( ID.toLatin1().data() )) {
2494         selectObject( aGeomSO );
2495         selectionDone();
2496       }
2497     }
2498   }
2499 }
2500
2501 //================================================================================
2502 /*!
2503  * \brief SLOT. Is called when Close is pressed in SMESHGUI_ShapeByMeshDlg
2504  */
2505 //================================================================================
2506 void SMESHGUI_MeshOp::onCloseShapeByMeshDlg(SUIT_Operation* op)
2507 {
2508   if ( myShapeByMeshOp == op && myDlg ) {
2509     myDlg->show();
2510   }
2511 }
2512
2513 //================================================================================
2514 /*!
2515  * \brief Selects a SObject
2516  * \param theSObj - the SObject to select
2517  */
2518 //================================================================================
2519 void SMESHGUI_MeshOp::selectObject( _PTR(SObject) theSObj ) const
2520 {
2521   if ( LightApp_SelectionMgr* sm = selectionMgr() ) {
2522     SALOME_ListIO anIOList;
2523     if ( theSObj ) {
2524       Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject
2525         ( theSObj->GetID().c_str(), "SMESH", theSObj->GetName().c_str() );
2526       anIOList.Append( anIO );
2527     }
2528     sm->setSelectedObjects( anIOList, false );
2529   }
2530 }
2531 //================================================================================
2532 /*!
2533  * \brief Create available list types of mesh
2534   * \param theTypeMesh - Output list of available types of mesh
2535  */
2536 //================================================================================
2537 void SMESHGUI_MeshOp::createMeshTypeList( QStringList& theTypeMesh)
2538 {
2539   theTypeMesh.clear();
2540   theTypeMesh.append( tr( "MT_ANY" ) );
2541   if ( myMaxShapeDim >= 2 || myMaxShapeDim == -1 )
2542   {
2543     theTypeMesh.append( tr( "MT_TRIANGULAR" ) );
2544     theTypeMesh.append( tr( "MT_QUADRILATERAL" ) );
2545   }
2546   if ( myMaxShapeDim == 3 || myMaxShapeDim == -1 )
2547   {
2548     theTypeMesh.append( tr( "MT_TETRAHEDRAL" ) );
2549     theTypeMesh.append( tr( "MT_HEXAHEDRAL" ) );
2550   }
2551
2552 }
2553 //================================================================================
2554 /*!
2555  * \brief Set available types of mesh
2556   * \param theTypeMesh - List of available types of mesh
2557  */
2558 //================================================================================
2559 void SMESHGUI_MeshOp::setAvailableMeshType( const QStringList& theTypeMesh )
2560 {
2561   myDlg->setAvailableMeshType( theTypeMesh );
2562 }
2563
2564 //================================================================================
2565 /*!
2566  * \brief SLOT. Is called when the user select type of mesh
2567   * \param theTabIndex - Index of current active tab
2568   * \param theIndex - Index of current type of mesh
2569  */
2570 //================================================================================
2571 void SMESHGUI_MeshOp::onAlgoSetByMeshType( const int theTabIndex, const int theIndex)
2572 {
2573   setFilteredAlgoData( theTabIndex, theIndex);
2574 }
2575
2576 //================================================================================
2577 /*!
2578  * \brief Set a filtered list of available algorithms by mesh type
2579   * \param theTabIndex - Index of current active tab
2580   * \param theIndex - Index of current type of mesh
2581  */
2582 //================================================================================
2583 void SMESHGUI_MeshOp::setFilteredAlgoData( const int theTabIndex, const int theIndex)
2584 {
2585   int aDim;
2586   THypDataList anAvailableAlgsData;
2587   QStringList anAvailableAlgs;
2588   QString anCompareType = "";
2589   bool isAvailableChoiceAlgo = false;
2590   int anCurrentAvailableAlgo = 0;
2591   bool isNone = true;
2592   switch ( theIndex ) {
2593   case MT_ANY:
2594     anCompareType = "ANY";
2595     aDim = SMESH::DIM_3D;
2596     break;
2597   case MT_TRIANGULAR:
2598     aDim = SMESH::DIM_2D;
2599     anCompareType = "TRIA";
2600     break;
2601   case MT_QUADRILATERAL:
2602     aDim = SMESH::DIM_2D;
2603     anCompareType = "QUAD";
2604     break;
2605   case MT_TETRAHEDRAL:
2606     aDim = SMESH::DIM_3D;
2607     anCompareType = "TETRA";
2608     break;
2609   case MT_HEXAHEDRAL:
2610     aDim = SMESH::DIM_3D;
2611     anCompareType = "HEXA";
2612     break;
2613   default:;
2614   }
2615
2616   bool toCheckIsApplicableToAll = !myIsMesh;
2617   GEOM::GEOM_Object_var aGeomVar;
2618   QString anEntry =
2619     myDlg->selectedObject( myToCreate ? SMESHGUI_MeshDlg::Geom : SMESHGUI_MeshDlg::Obj );
2620   if ( _PTR(SObject) so = studyDS()->FindObjectID( anEntry.toLatin1().data() ))
2621   {
2622     aGeomVar = SMESH::GetGeom( so );
2623     if ( !aGeomVar->_is_nil() && toCheckIsApplicableToAll )
2624       toCheckIsApplicableToAll = ( aGeomVar->GetType() == GEOM_GROUP );
2625   }
2626
2627   if ( anCompareType == "ANY" )
2628   {
2629     for ( int dim = SMESH::DIM_3D; dim >= SMESH::DIM_2D; dim-- )
2630     {
2631       isNone = currentHyp( dim, Algo ) < 0;
2632       isAvailableChoiceAlgo = false;
2633       // retrieves a list of available algorithms from resources
2634       availableHyps( dim, Algo, anAvailableAlgs, anAvailableAlgsData );
2635       //return current algo in current tab and set new algorithm list
2636       HypothesisData* algoCur;
2637       if ( !isNone && !myAvailableHypData[dim][Algo].empty() ) {
2638         algoCur = myAvailableHypData[dim][Algo].at( currentHyp( dim, Algo ) );
2639       }
2640       myAvailableHypData[dim][Algo].clear();
2641       anAvailableAlgs.clear();
2642       if ( dim != SMESH::DIM_2D || currentHyp( SMESH::DIM_3D, Algo ) < 0 ||
2643            myAvailableHypData[SMESH::DIM_3D][Algo].empty() ||
2644            !myAvailableHypData[SMESH::DIM_3D][Algo].at( currentHyp( SMESH::DIM_3D, Algo ) )->InputTypes.isEmpty() )
2645       {
2646         for (int i = 0 ; i < anAvailableAlgsData.count(); i++)
2647         {
2648           HypothesisData* curAlgo = anAvailableAlgsData.at(i);
2649           if ( aGeomVar->_is_nil() ||
2650               SMESH::IsApplicable( curAlgo->TypeName, aGeomVar, toCheckIsApplicableToAll ))
2651           {
2652             anAvailableAlgs.append( curAlgo->Label );
2653             myAvailableHypData[dim][Algo].append( curAlgo );
2654           }
2655         }
2656         if ( !isNone && algoCur ) {
2657           for (int i = 0 ; i < myAvailableHypData[dim][Algo].count(); i++)
2658           {
2659             HypothesisData* algoAny = myAvailableHypData[dim][Algo].at(i);
2660             if ( algoAny->Label == algoCur->Label ){
2661               isAvailableChoiceAlgo = true;
2662               anCurrentAvailableAlgo = i;
2663               break;
2664             }
2665           }
2666         }
2667         else if ( !isNone ) {
2668           isAvailableChoiceAlgo = true;
2669           anCurrentAvailableAlgo = currentHyp( dim, Algo );
2670         }
2671       }
2672       myDlg->tab( dim )->setAvailableHyps( Algo, anAvailableAlgs );
2673       if ( isAvailableChoiceAlgo )
2674         setCurrentHyp( dim, Algo, anCurrentAvailableAlgo );
2675     }
2676     if ( !myIsOnGeometry )
2677       for ( int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++ ) {
2678         if ( i < SMESH::DIM_3D ) myDlg->disableTab( i );
2679         else                     myDlg->enableTab( i );
2680       }
2681     else
2682       for ( int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++ ) {
2683         if ( i > myMaxShapeDim ) myDlg->disableTab( i );
2684         else                     myDlg->enableTab( i );
2685       }
2686     myDlg->setCurrentTab( theTabIndex );
2687   }
2688   else
2689   {
2690     QString anCurrentAlgo;
2691     bool isReqDisBound = true;
2692     QString anCurrentCompareType = anCompareType;
2693     isNone = currentHyp( aDim, Algo ) < 0;
2694     if ( !isNone && !myAvailableHypData[aDim][Algo].empty() &&
2695         myAvailableHypData[aDim][Algo].count() != anAvailableAlgsData.count() )
2696       isReqDisBound = myAvailableHypData[aDim][Algo].at( currentHyp( aDim, Algo ) )->InputTypes.isEmpty();
2697     else if ( !isNone )
2698       isReqDisBound = anAvailableAlgsData.at( currentHyp( aDim, Algo ) )->InputTypes.isEmpty();
2699     for ( int dim = aDim; dim >= SMESH::DIM_2D; dim-- )
2700     {
2701       bool isNoneAlg = currentHyp( dim, Algo ) < 0;
2702       isAvailableChoiceAlgo = false;
2703       // retrieves a list of available algorithms from resources
2704       availableHyps( dim, Algo, anAvailableAlgs, anAvailableAlgsData );
2705       // finding algorithm which is selected
2706       if ( !isNoneAlg && !myAvailableHypData[dim][Algo].empty() &&
2707           myAvailableHypData[dim][Algo].count() != anAvailableAlgsData.count() )
2708         anCurrentAlgo = myAvailableHypData[dim][Algo].at( currentHyp( dim, Algo ) )->Label;
2709       else if ( !isNoneAlg )
2710         anCurrentAlgo = anAvailableAlgsData.at( currentHyp( dim, Algo ) )->Label;
2711       anAvailableAlgs.clear();
2712       myAvailableHypData[dim][Algo].clear();
2713       myFilteredAlgoData[dim].clear();
2714       // finding and adding algorithm depending on the type mesh
2715       for ( int i = 0 ; i < anAvailableAlgsData.count(); i++ )
2716       {
2717         HypothesisData* algoIn = anAvailableAlgsData.at( i );
2718         bool isAvailableAlgo = ( algoIn->OutputTypes.count() == 0 );
2719         QStringList::const_iterator inElemType = algoIn->OutputTypes.begin();
2720         for ( ; inElemType != algoIn->OutputTypes.end(); inElemType++ )
2721         {
2722           if ( *inElemType == anCurrentCompareType ) {
2723             isAvailableAlgo = true;
2724             break;
2725           }
2726         }
2727         if ( isAvailableAlgo || algoIn->OutputTypes.count()==0 ) {
2728           if ( aGeomVar->_is_nil() || myMaxShapeDim != dim ||
2729                SMESH::IsApplicable( algoIn->TypeName, aGeomVar, toCheckIsApplicableToAll ))
2730           {
2731             anAvailableAlgs.append( algoIn->Label );
2732             myAvailableHypData[dim][Algo].append( algoIn );
2733             myFilteredAlgoData[dim].append( algoIn );
2734           }
2735         }
2736         //algorithm will be active, if the chosen algorithm available in the current mesh type
2737         if ( !isNoneAlg &&  isAvailableAlgo && algoIn->Label == anCurrentAlgo ) {
2738           isAvailableChoiceAlgo = true;
2739           anCurrentAvailableAlgo = anAvailableAlgs.count() - 1 ;
2740         }
2741       }
2742       //set new algorithm list and select the current algorithm
2743       myDlg->tab( dim )->setAvailableHyps( Algo, anAvailableAlgs );
2744       anCurrentCompareType = ( anCompareType == "HEXA" ) ? "QUAD" : "TRIA";
2745       if ( isAvailableChoiceAlgo )
2746         setCurrentHyp( dim, Algo, anCurrentAvailableAlgo );
2747       else
2748         setCurrentHyp( dim, Algo, -1 );
2749     }
2750
2751     if ( isNone || isReqDisBound ) {
2752       for ( int i = SMESH::DIM_0D; i <= myMaxShapeDim; i++ ) {
2753         if ( aDim != i ) {
2754           myDlg->disableTab( i );
2755           setCurrentHyp(i, Algo, -1);
2756         }
2757       }
2758     }
2759     else if ( !isNone ) {
2760       if ( aDim == SMESH::DIM_2D){
2761         myDlg->disableTab( SMESH::DIM_3D );
2762         setCurrentHyp( SMESH::DIM_3D, Algo, -1);
2763       }
2764       for ( int i = myMaxShapeDim; i > SMESH::DIM_0D; i-- )
2765       {
2766         isReqDisBound = ( currentHyp( i, Algo ) < 0 ) ? true :
2767             myAvailableHypData[i][Algo].at( currentHyp( i, Algo ) )->InputTypes.isEmpty();
2768         if ( isReqDisBound ) {
2769           for (int j = i - 1; j >= SMESH::DIM_0D; j--){
2770             myDlg->disableTab( j );
2771             setCurrentHyp( j , Algo, -1 );
2772           }
2773           break;
2774         }
2775       }
2776     }
2777     myDlg->enableTab( aDim );
2778     myDlg->setCurrentTab( aDim );
2779   }
2780   QStringList aHypothesesSetsList = SMESH::GetHypothesesSets( aDim );
2781   QStringList aFilteredHypothesesSetsList;
2782   aFilteredHypothesesSetsList.clear();
2783   QStringList::const_iterator inHypoSetName = aHypothesesSetsList.begin();
2784   for ( ; inHypoSetName != aHypothesesSetsList.end(); ++inHypoSetName )
2785   {
2786     HypothesesSet* currentHypoSet = SMESH::GetHypothesesSet( *inHypoSetName );
2787     bool isAvailable = false;
2788     currentHypoSet->init( true );
2789     while ( currentHypoSet->next(), currentHypoSet->more() )
2790     {
2791       isAvailable = false;
2792       if ( HypothesisData* algoDataIn = SMESH::GetHypothesisData( currentHypoSet->current() ))
2793       {
2794         for (int i = SMESH::DIM_0D; i <= myMaxShapeDim; i++)
2795         {
2796           if ( myAvailableHypData[i][Algo].count() == 0 ) {
2797             availableHyps( i, Algo, anAvailableAlgs, anAvailableAlgsData );
2798             for ( int j = 0 ; j < anAvailableAlgsData.count(); j++ )
2799             {
2800               HypothesisData* aCurAlgo = anAvailableAlgsData.at( j );
2801               if ( aCurAlgo->Label == algoDataIn->Label ){
2802                 isAvailable = true;
2803                 break;
2804               }
2805             }
2806           }
2807           else {
2808             for (int j = 0; j < myAvailableHypData[i][Algo].count(); ++j) {
2809               HypothesisData* aCurAlgo = hypData( i, Algo, j );
2810               if ( aCurAlgo->Label == algoDataIn->Label ){
2811                 isAvailable = true;
2812                 break;
2813               }
2814             }
2815           }
2816           if ( isAvailable ) break;
2817         }
2818         if ( !isAvailable ) break;
2819       }
2820     }
2821     if ( isAvailable )
2822       aFilteredHypothesesSetsList.append( *inHypoSetName );
2823   }
2824   myDlg->setHypoSets( aFilteredHypothesesSetsList );
2825 }