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