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