Salome HOME
Update Help references (bug 17577)
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_MeshOp.cxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 //
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
8 //
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20 /**
21 *  SMESH SMESHGUI
22 *
23 *  Copyright (C) 2005  CEA/DEN, EDF R&D
24 *
25 *
26 *
27 *  File   : SMESHGUI_MeshOp.h
28 *  Author : Sergey LITONIN
29 *  Module : SMESHGUI
30 */
31
32 #include "SMESHGUI_MeshOp.h"
33 #include "SMESHGUI_MeshDlg.h"
34 #include "SMESHGUI_ShapeByMeshDlg.h"
35 #include "SMESH_TypeFilter.hxx"
36 #include "SMESHGUI.h"
37
38 #include "SMESHGUI_HypothesesUtils.h"
39 #include "SMESHGUI_Hypotheses.h"
40 #include "SMESHGUI_Utils.h"
41 #include "SMESHGUI_GEOMGenUtils.h"
42 #include "SMESHGUI_VTKUtils.h"
43
44 #include "SMESH_TypeFilter.hxx"
45 #include "SMESH_NumberFilter.hxx"
46
47 #include "GEOM_SelectionFilter.h"
48 #include "GEOMBase.h"
49 #include "GeometryGUI.h"
50
51 #include "SalomeApp_Tools.h"
52 #include "SalomeApp_Application.h"
53 #include "SALOMEDSClient_Study.hxx"
54 #include "SALOMEDSClient_AttributeIOR.hxx"
55 #include "SALOMEDSClient_AttributeName.hxx"
56 #include "SALOMEDS_SComponent.hxx"
57 #include "SALOMEDS_SObject.hxx"
58
59 #include "LightApp_SelectionMgr.h"
60 #include "LightApp_UpdateFlags.h"
61 #include "SUIT_MessageBox.h"
62 #include "SUIT_Desktop.h"
63 #include "SUIT_OverrideCursor.h"
64 #include "SALOME_InteractiveObject.hxx"
65 #include "SALOME_ListIO.hxx"
66
67 #include "utilities.h"
68
69 #include <qstringlist.h>
70 #include <qlineedit.h>
71
72 #include <TopoDS_Shape.hxx>
73 #include <TopExp_Explorer.hxx>
74
75 enum { GLOBAL_ALGO_TAG        =3,
76        GLOBAL_HYPO_TAG        =2,
77        LOCAL_ALGO_TAG         =2,
78        LOCAL_HYPO_TAG         =1,
79        SUBMESH_ON_VERTEX_TAG  =4,
80        SUBMESH_ON_EDGE_TAG    =5,
81        SUBMESH_ON_WIRE_TAG    =6,
82        SUBMESH_ON_FACE_TAG    =7,
83        SUBMESH_ON_SHELL_TAG   =8,
84        SUBMESH_ON_SOLID_TAG   =9,
85        SUBMESH_ON_COMPOUND_TAG=10 };
86
87 //================================================================================
88 /*!
89  * \brief Constructor
90   * \param theToCreate - if this parameter is true then operation is used for creation,
91   * for editing otherwise
92  *
93  * Initialize operation
94 */
95 //================================================================================
96 SMESHGUI_MeshOp::SMESHGUI_MeshOp( const bool theToCreate, const bool theIsMesh )
97 : SMESHGUI_SelectionOp(),
98   myToCreate( theToCreate ),
99   myIsMesh( theIsMesh ),
100   myDlg( 0 ),
101   myShapeByMeshOp( 0 )
102 {
103   if ( GeometryGUI::GetGeomGen()->_is_nil() )// check that GEOM_Gen exists
104     GeometryGUI::InitGeomGen();
105   myIsOnGeometry = true;
106 }
107
108 //================================================================================
109 /*!
110  * \brief Destructor
111 */
112 //================================================================================
113 SMESHGUI_MeshOp::~SMESHGUI_MeshOp()
114 {
115   if ( myDlg )
116     delete myDlg;
117 }
118
119 //================================================================================
120 /*!
121  * \brief Gets dialog of this operation
122   * \retval LightApp_Dialog* - pointer to dialog of this operation
123 */
124 //================================================================================
125 LightApp_Dialog* SMESHGUI_MeshOp::dlg() const
126 {
127   return myDlg;
128 }
129
130 //================================================================================
131 /*!
132  * \brief Creates or edits mesh
133   * \retval bool - TRUE if operation is performed successfully, FALSE otherwise
134  *
135  * Virtual slot redefined from the base class called when "Apply" button is clicked
136  * creates or edits mesh
137  */
138 //================================================================================
139 bool SMESHGUI_MeshOp::onApply()
140 {
141   if( isStudyLocked() )
142     return false;
143
144   QString aMess;
145   if ( !isValid( aMess ) )
146   {
147     dlg()->show();
148     if ( aMess != "" )
149       SUIT_MessageBox::warn1( myDlg,
150         tr( "SMESH_WRN_WARNING" ), aMess, tr( "SMESH_BUT_OK" ) );
151     return false;
152   }
153
154   bool aResult = false;
155   aMess = "";
156   try
157   {
158     if ( myToCreate && myIsMesh )
159       aResult = createMesh( aMess );
160     if ( myToCreate && !myIsMesh )
161       aResult = createSubMesh( aMess );
162     else if ( !myToCreate )
163       aResult = editMeshOrSubMesh( aMess );
164     if ( aResult )
165       update( UF_ObjBrowser | UF_Model );
166   }
167   catch ( const SALOME::SALOME_Exception& S_ex )
168   {
169     SalomeApp_Tools::QtCatchCorbaException( S_ex );
170     aResult = false;
171   }
172   catch ( ... )
173   {
174     aResult = false;
175   }
176
177   if ( aResult )
178   {
179     if ( myToCreate )
180       setDefaultName();
181   }
182   else
183   {
184     if ( aMess == "" )
185       aMess = tr( "SMESH_OPERATION_FAILED" );
186     SUIT_MessageBox::warn1( myDlg,
187       tr( "SMESH_ERROR" ), aMess, tr( "SMESH_BUT_OK" ) );
188   }
189
190   return aResult;
191 }
192
193 //================================================================================
194 /*!
195  * \brief Creates dialog if necessary and shows it
196  *
197  * Virtual method redefined from base class called when operation is started creates
198  * dialog if necessary and shows it, activates selection
199  */
200 //================================================================================
201 void SMESHGUI_MeshOp::startOperation()
202 {
203   if( !myDlg )
204   {
205     myDlg = new SMESHGUI_MeshDlg( myToCreate, myIsMesh );
206     for ( int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++ )
207     {
208       connect( myDlg->tab( i ), SIGNAL( createHyp( const int, const int ) ),
209               this, SLOT( onCreateHyp( const int, const int ) ) );
210       connect( myDlg->tab( i ), SIGNAL( editHyp( const int, const int ) ),
211               this, SLOT( onEditHyp( const int, const int ) ) );
212       connect( myDlg->tab( i ), SIGNAL( selectAlgo( const int ) ),
213               this, SLOT( onAlgoSelected( const int ) ) );
214     }
215     connect( myDlg, SIGNAL( hypoSet( const QString& )), SLOT( onHypoSet( const QString& )));
216     connect( myDlg, SIGNAL( geomSelectionByMesh( bool )), SLOT( onGeomSelectionByMesh( bool )));
217
218     if ( myToCreate )
219       if ( myIsMesh ) myHelpFileName = "constructing_meshes_page.html";
220       else myHelpFileName = "constructing_submeshes_page.html";
221     else myHelpFileName = "editing_meshes_page.html";
222   }
223   SMESHGUI_SelectionOp::startOperation();
224
225   // iterate through dimensions and get available algoritms, set them to the dialog
226   _PTR(SComponent) aFather = SMESH::GetActiveStudyDocument()->FindComponent( "SMESH" );
227   for ( int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++ )
228   {
229     SMESHGUI_MeshTab* aTab = myDlg->tab( i );
230     QStringList hypList;
231     // clear available hypotheses
232     aTab->setAvailableHyps( MainHyp, hypList );
233     aTab->setAvailableHyps( AddHyp, hypList );
234     aTab->setExistingHyps( MainHyp, hypList );
235     aTab->setExistingHyps( AddHyp, hypList );
236     myExistingHyps[ i ][ MainHyp ].clear();
237     myExistingHyps[ i ][ AddHyp ].clear();
238     // set algos
239     availableHyps( i, Algo, hypList, myAvailableHypData[i][Algo] );
240     aTab->setAvailableHyps( Algo, hypList );
241   }
242   if ( myToCreate )
243   {
244     setDefaultName();
245     myDlg->activateObject( myIsMesh ? SMESHGUI_MeshDlg::Geom : SMESHGUI_MeshDlg::Mesh );
246   }
247   else
248     myDlg->activateObject( SMESHGUI_MeshDlg::Obj );
249
250   myDlg->setHypoSets( SMESH::GetHypothesesSets() );
251
252   myDlg->setCurrentTab( SMESH::DIM_3D );
253   myDlg->show();
254
255   selectionDone();
256
257   myIgnoreAlgoSelection = false;
258 }
259
260 //================================================================================
261 /*!
262  * \brief Creates selection filter
263   * \param theId - identifier of current selection widget
264   * \retval SUIT_SelectionFilter* - pointer to the created filter or null
265  *
266  * Creates selection filter in accordance with identifier of current selection widget
267  */
268 //================================================================================
269 SUIT_SelectionFilter* SMESHGUI_MeshOp::createFilter( const int theId ) const
270 {
271   if ( theId == SMESHGUI_MeshDlg::Geom )
272   {
273 //     TColStd_MapOfInteger allTypesMap;
274 //     for ( int i = 0; i < 10; i++ )
275 //       allTypesMap.Add( i );
276 //     return new SMESH_NumberFilter( "GEOM", TopAbs_SHAPE, 0, allTypesMap );
277     return new GEOM_SelectionFilter( (SalomeApp_Study*)study(), true );
278   }
279   else if ( theId == SMESHGUI_MeshDlg::Obj && !myToCreate )
280     return new SMESH_TypeFilter( MESHorSUBMESH );
281   else if ( theId == SMESHGUI_MeshDlg::Mesh )
282     return new SMESH_TypeFilter( MESH );
283   else
284     return 0;
285 }
286
287 //================================================================================
288 /*!
289  * \brief check if selected shape is a subshape of the shape to mesh
290   * \retval bool - check result
291  */
292 //================================================================================
293
294 bool SMESHGUI_MeshOp::isSubshapeOk() const
295 {
296   if ( !myToCreate || myIsMesh ) // not submesh creation
297     return false;
298
299   // mesh
300   QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
301   _PTR(SObject) pMesh = studyDS()->FindObjectID( aMeshEntry.latin1() );
302   if (!pMesh) return false;
303
304   SMESH::SMESH_Mesh_var mesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( pMesh );
305   if (mesh->_is_nil()) return false;
306
307   // main shape of the mesh
308   GEOM::GEOM_Object_var mainGeom = mesh->GetShapeToMesh();
309   if (mainGeom->_is_nil()) return false;
310
311   // geometry
312   QStringList aGEOMs;
313   myDlg->selectedObject(SMESHGUI_MeshDlg::Geom, aGEOMs);
314
315   if (aGEOMs.count() > 0) {
316     GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen();
317     _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
318     if (geomGen->_is_nil() || !aStudy) return false;
319
320     GEOM::GEOM_IGroupOperations_var op =
321         geomGen->GetIGroupOperations(aStudy->StudyId());
322     if (op->_is_nil()) return false;
323
324     // check all selected shapes
325     QStringList::const_iterator aSubShapesIter = aGEOMs.begin();
326     for (; aSubShapesIter != aGEOMs.end(); aSubShapesIter++) {
327       QString aSubGeomEntry = (*aSubShapesIter);
328       _PTR(SObject) pSubGeom = studyDS()->FindObjectID(aSubGeomEntry.latin1());
329       if (!pSubGeom) return false;
330
331       GEOM::GEOM_Object_var aSubGeomVar =
332         GEOM::GEOM_Object::_narrow(_CAST(SObject,pSubGeom)->GetObject());
333       if (aSubGeomVar->_is_nil()) return false;
334
335       // skl for NPAL14695 - implementation of searching of mainObj
336       GEOM::GEOM_Object_var mainObj = op->GetMainShape(aSubGeomVar);
337       //if (mainObj->_is_nil() ||
338       //    string(mainObj->GetEntry()) != string(mainGeom->GetEntry())) return false;
339       while(1) {
340         if(mainObj->_is_nil())
341           return false;
342         if( string(mainObj->GetEntry()) == string(mainGeom->GetEntry()) )
343           return true;
344         mainObj = op->GetMainShape(mainObj);
345       }
346     }
347     //return true;
348   }
349
350   return false;
351 }
352
353 //================================================================================
354 /*!
355  * \brief find an existing submesh by the selected shape
356   * \retval _PTR(SObject) - the found submesh SObject
357  */
358 //================================================================================
359
360 _PTR(SObject) SMESHGUI_MeshOp::getSubmeshByGeom() const
361 {
362   QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
363   QString aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
364   _PTR(SObject) pMesh = studyDS()->FindObjectID( aMeshEntry.latin1() );
365   _PTR(SObject) pGeom = studyDS()->FindObjectID( aGeomEntry.latin1() );
366   if ( pMesh && pGeom ) {
367     GEOM::GEOM_Object_var geom = SMESH::SObjectToInterface<GEOM::GEOM_Object>( pGeom );
368     if ( !geom->_is_nil() ) {
369       int tag = -1;
370       switch ( geom->GetShapeType() ) {
371       case GEOM::VERTEX:   tag = SUBMESH_ON_VERTEX_TAG  ; break;
372       case GEOM::EDGE:     tag = SUBMESH_ON_EDGE_TAG    ; break;
373       case GEOM::WIRE:     tag = SUBMESH_ON_WIRE_TAG    ; break;
374       case GEOM::FACE:     tag = SUBMESH_ON_FACE_TAG    ; break;
375       case GEOM::SHELL:    tag = SUBMESH_ON_SHELL_TAG   ; break;
376       case GEOM::SOLID:    tag = SUBMESH_ON_SOLID_TAG   ; break;
377       case GEOM::COMPOUND: tag = SUBMESH_ON_COMPOUND_TAG; break;
378       default:;
379       }
380       _PTR(GenericAttribute) anAttr;
381       _PTR(SObject) aSubmeshRoot;
382       _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
383       if ( pMesh->FindSubObject( tag, aSubmeshRoot ) )
384       {
385         _PTR(ChildIterator) smIter = aStudy->NewChildIterator( aSubmeshRoot );
386         for (; smIter->More(); smIter->Next() )
387         {
388           _PTR(SObject) aSmObj = smIter->Value();
389           if ( ! aSmObj->FindAttribute( anAttr, "AttributeIOR" ))
390             continue;
391           _PTR(ChildIterator) anIter1 = aStudy->NewChildIterator(aSmObj);
392           for (; anIter1->More(); anIter1->Next()) {
393             _PTR(SObject) pGeom2 = anIter1->Value();
394             if ( pGeom2->ReferencedObject( pGeom2 ) &&
395                  pGeom2->GetID() == pGeom->GetID() )
396               return aSmObj;
397           }
398         }
399       }
400     }
401   }
402   return _PTR(SObject)();
403 }
404
405 //================================================================================
406 /*!
407  * \brief Updates dialog's look and feel
408  *
409  * Virtual method redefined from the base class updates dialog's look and feel
410  */
411 //================================================================================
412 void SMESHGUI_MeshOp::selectionDone()
413 {
414   if ( !dlg()->isShown() || !myDlg->isEnabled() )
415     return;
416   
417   SMESHGUI_SelectionOp::selectionDone();
418   
419   try
420   {
421     //Check geometry for mesh
422     QString anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
423     _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.latin1() );
424     if ( !pObj )
425       return;
426     
427     SMESH::SMESH_subMesh_var aSubMeshVar =
428       SMESH::SMESH_subMesh::_narrow( _CAST( SObject,pObj )->GetObject() );
429     if ( !aSubMeshVar->_is_nil() ) 
430       myIsOnGeometry = true;
431     else {
432       SMESH::SMESH_Mesh_var aMeshVar =
433         SMESH::SMESH_Mesh::_narrow( _CAST( SObject,pObj )->GetObject() );
434       if ( !myToCreate && !aMeshVar->HasShapeToMesh() )
435         myIsOnGeometry = false;
436       else
437         myIsOnGeometry = true;
438     }
439     
440     if ( myIsOnGeometry ) {
441       // Enable tabs according to shape dimension
442     
443       int shapeDim = 3;
444       QStringList aGEOMs;
445       myDlg->selectedObject(SMESHGUI_MeshDlg::Geom, aGEOMs);
446       GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO;
447
448       if (aGEOMs.count() > 0) {
449         // one or more GEOM shape selected
450         aSeq->length(aGEOMs.count());
451         QStringList::const_iterator aSubShapesIter = aGEOMs.begin();
452         int iSubSh = 0;
453         for (; aSubShapesIter != aGEOMs.end(); aSubShapesIter++, iSubSh++) {
454           QString aSubGeomEntry = (*aSubShapesIter);
455           _PTR(SObject) pSubGeom = studyDS()->FindObjectID(aSubGeomEntry.latin1());
456           GEOM::GEOM_Object_var aSubGeomVar =
457             GEOM::GEOM_Object::_narrow(_CAST(SObject,pSubGeom)->GetObject());
458           aSeq[iSubSh] = aSubGeomVar;
459         }
460       } else {
461         // get geometry by selected sub-mesh
462         QString anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
463         _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.latin1() );
464         GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj );
465         if (!aGeomVar->_is_nil()) {
466           aSeq->length(1);
467           aSeq[0] = aGeomVar;
468         }
469       }
470
471       if (aSeq->length() > 0) {
472         shapeDim = 0;
473         for (int iss = 0; iss < aSeq->length() && shapeDim < 3; iss++) {
474           GEOM::GEOM_Object_var aGeomVar = aSeq[iss];
475           switch ( aGeomVar->GetShapeType() ) {
476           case GEOM::SOLID:
477           case GEOM::SHELL:  shapeDim = 3; break;
478           case GEOM::FACE:   shapeDim = (shapeDim < 2) ? 2 : shapeDim; break;
479           case GEOM::WIRE:
480           case GEOM::EDGE:   shapeDim = (shapeDim < 1) ? 1 : shapeDim; break;
481           case GEOM::VERTEX: break;
482           default:
483             TopoDS_Shape aShape;
484             if ( GEOMBase::GetShape(aGeomVar, aShape)) {
485               TopExp_Explorer exp( aShape, TopAbs_SHELL );
486               if ( exp.More() )
487                 shapeDim = 3;
488               else if ( exp.Init( aShape, TopAbs_FACE ), exp.More() )
489                 shapeDim = (shapeDim < 2) ? 2 : shapeDim;
490               else if ( exp.Init( aShape, TopAbs_EDGE ), exp.More() )
491                 shapeDim = (shapeDim < 1) ? 1 : shapeDim;
492               else
493                 ;//shapeDim = 0;
494             }
495           }
496         }
497       }
498       myDlg->setMaxHypoDim( shapeDim );
499
500       
501       if ( !myToCreate ) // edition: read hypotheses
502       {
503         QString anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
504         _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.latin1() );
505         if ( pObj != 0 )
506         {
507           
508           SMESH::SMESH_subMesh_var aVar =
509             SMESH::SMESH_subMesh::_narrow( _CAST( SObject,pObj )->GetObject() );
510           myDlg->setObjectShown( SMESHGUI_MeshDlg::Mesh, !aVar->_is_nil() );
511           myDlg->setObjectShown( SMESHGUI_MeshDlg::Geom, true );
512           myDlg->objectWg( SMESHGUI_MeshDlg::Mesh, SMESHGUI_MeshDlg::Btn )->hide();
513           myDlg->objectWg( SMESHGUI_MeshDlg::Geom, SMESHGUI_MeshDlg::Btn )->hide();
514           myDlg->updateGeometry();
515           myDlg->adjustSize();
516           readMesh();
517         }
518         else
519           myDlg->reset();
520         
521       }
522       else if ( !myIsMesh ) // submesh creation
523       {
524         // if a submesh on the selected shape already exist, pass to submesh edition mode
525         if ( _PTR(SObject) pSubmesh = getSubmeshByGeom() ) {
526           SMESH::SMESH_subMesh_var sm =
527             SMESH::SObjectToInterface<SMESH::SMESH_subMesh>( pSubmesh );
528           bool editSubmesh = ( !sm->_is_nil() &&
529                                SUIT_MessageBox::question2( myDlg, tr( "SMESH_WARNING" ),
530                                                            tr( "EDIT_SUBMESH_QUESTION"),
531                                                            tr( "SMESH_BUT_YES" ),
532                                                            tr( "SMESH_BUT_NO" ), 1, 0, 0 ));
533           if ( editSubmesh )
534           {
535             selectionMgr()->clearFilters();
536             selectObject( pSubmesh );
537             SMESHGUI::GetSMESHGUI()->switchToOperation(704);
538             return;
539           }
540           else
541           {
542             myDlg->selectObject( "", SMESHGUI_MeshDlg::Geom, "" );
543             selectObject( _PTR(SObject)() );
544             selectionDone();
545           }
546         }
547         
548         // enable/disable popup for choice of geom selection way
549         bool enable = false;
550         QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
551         if ( _PTR(SObject) pMesh = studyDS()->FindObjectID( aMeshEntry.latin1() )) {
552           SMESH::SMESH_Mesh_var mesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( pMesh );
553           if ( !mesh->_is_nil() )
554             enable = ( shapeDim > 1 ) && ( mesh->NbEdges() > 0 );
555         }
556         myDlg->setGeomPopupEnabled( enable );
557       }
558     }
559     else {
560       myDlg->enableTab( SMESH::DIM_3D );
561       QStringList hypList;
562       availableHyps( SMESH::DIM_3D, Algo, hypList,
563                      myAvailableHypData[SMESH::DIM_3D][Algo]);
564       
565       SMESHGUI_MeshTab* aTab = myDlg->tab( SMESH::DIM_3D );
566       aTab->setAvailableHyps( Algo, hypList );
567       for( int i = SMESH::DIM_0D;i < SMESH::DIM_3D; ++i ) {
568         myDlg->disableTab(i);
569       }
570       //Hide labels and fields (Mesh ang Geometry)
571       myDlg->setObjectShown( SMESHGUI_MeshDlg::Mesh, false );
572       myDlg->setObjectShown( SMESHGUI_MeshDlg::Geom, false );
573       myDlg->adjustSize();
574       readMesh();
575     }
576   }
577   catch ( const SALOME::SALOME_Exception& S_ex )
578   {
579     SalomeApp_Tools::QtCatchCorbaException( S_ex );
580   }
581   catch ( ... )
582   {
583   }
584 }
585
586 //================================================================================
587 /*!
588  * \brief Verifies validity of input data
589   * \param theMess - Output parameter intended for returning error message
590   * \retval bool  - TRUE if input data is valid, false otherwise
591  *
592  * Verifies validity of input data. This method is called when "Apply" or "OK" button
593  * is pressed before mesh creation or editing.
594  */
595 //================================================================================
596 bool SMESHGUI_MeshOp::isValid( QString& theMess ) const
597 {
598   // Selected object to be  edited
599   if ( !myToCreate && myDlg->selectedObject( SMESHGUI_MeshDlg::Obj ) == "" )
600   {
601     theMess = tr( "THERE_IS_NO_OBJECT_FOR_EDITING" );
602     return false;
603   }
604
605   // Name
606   QString aMeshName = myDlg->objectText( SMESHGUI_MeshDlg::Obj );
607   aMeshName = aMeshName.stripWhiteSpace();
608   if ( aMeshName == "" )
609   {
610     theMess = myIsMesh ? tr( "NAME_OF_MESH_IS_EMPTY" ) : tr( "NAME_OF_SUBMESH_IS_EMPTY" );
611     return false;
612   }
613
614 /*  // Imported mesh, if create sub-mesh or edit mesh
615   if ( !myToCreate || ( myToCreate && !myIsMesh ))
616   {
617     QString aMeshEntry = myDlg->selectedObject
618       ( myToCreate ? SMESHGUI_MeshDlg::Mesh : SMESHGUI_MeshDlg::Obj );
619     if ( _PTR(SObject) pMesh = studyDS()->FindObjectID( aMeshEntry.latin1() )) {
620       SMESH::SMESH_Mesh_var mesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( pMesh );
621       if ( !mesh->_is_nil() && CORBA::is_nil( mesh->GetShapeToMesh() )) {
622         theMess = tr( "IMPORTED_MESH" );
623         return false;
624       }
625     }
626   }*/
627
628   // Geom
629   if ( myToCreate )
630   {
631     QString aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
632     if ( aGeomEntry == "" )
633     {
634       theMess = tr( "GEOMETRY_OBJECT_IS_NOT_DEFINED" );
635       return false;
636     }
637     _PTR(SObject) pGeom = studyDS()->FindObjectID( aGeomEntry.latin1() );
638     if ( !pGeom || GEOM::GEOM_Object::_narrow( _CAST( SObject,pGeom )->GetObject() )->_is_nil() )
639     {
640       theMess = tr( "GEOMETRY_OBJECT_IS_NULL" );
641       return false;
642     }
643
644     // Mesh
645     if ( !myIsMesh ) // i.e sub-mesh creation,
646     {
647       QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
648       if ( aMeshEntry == "" )
649       {
650         theMess = tr( "MESH_IS_NOT_DEFINED" );
651         return false;
652       }
653       _PTR(SObject) pMesh = studyDS()->FindObjectID( aMeshEntry.latin1() );
654       if ( !pMesh || SMESH::SMESH_Mesh::_narrow( _CAST( SObject,pMesh )->GetObject() )->_is_nil() )
655       {
656         theMess = tr( "MESH_IS_NULL" );
657         return false;
658       }
659       if ( !isSubshapeOk() )
660       {
661         theMess = tr( "INVALID_SUBSHAPE" );
662         return false;
663       }
664     }
665   }
666
667   return true;
668 }
669
670 //================================================================================
671 /*!
672  * \brief check compatibility of the algorithm and another algorithm or hypothesis
673   * \param theAlgoData - algorithm data
674   * \param theHypData - hypothesis data
675   * \param theHypType - hypothesis type
676   * \param theHypTypeName - hypothesis type name, must be provided if 2-nd arg is not algo
677   * \retval bool - check result
678  */
679 //================================================================================
680
681 static bool isCompatible(const HypothesisData* theAlgoData,
682                          const HypothesisData* theHypData,
683                          const int             theHypType)
684 {
685   if ( !theAlgoData )
686     return true;
687
688   if ( theHypType == SMESHGUI_MeshOp::Algo )
689     return SMESH::IsCompatibleAlgorithm( theAlgoData, theHypData );
690
691   bool isOptional;
692   return ( SMESH::IsAvailableHypothesis( theAlgoData, theHypData->TypeName, isOptional ));
693 }
694
695 //================================================================================
696 /*!
697  * \brief Gets available hypotheses or algorithms
698   * \param theDim - specifies dimension of returned hypotheses/algorifms
699   * \param theHypType - specifies whether algorims or hypotheses or additional ones
700   * are retrieved (possible values are in HypType enumeration)
701   * \param theHyps - Output list of hypotheses' names
702   * \param theAlgoData - to select hypos able to be used by this algo (optional)
703  *
704  * Gets available hypotheses or algorithm in accordance with input parameters
705  */
706 //================================================================================
707 void SMESHGUI_MeshOp::availableHyps( const int       theDim,
708                                      const int       theHypType,
709                                      QStringList&    theHyps,
710                                      THypDataList&   theDataList,
711                                      HypothesisData* theAlgoData ) const
712 {
713   theDataList.clear();
714   theHyps.clear();
715   bool isAlgo = ( theHypType == Algo );
716   bool isAux  = ( theHypType == AddHyp );
717   QStringList aHypTypeNameList = SMESH::GetAvailableHypotheses( isAlgo, theDim, isAux, myIsOnGeometry );
718
719   QStringList::const_iterator anIter;
720   for ( anIter = aHypTypeNameList.begin(); anIter != aHypTypeNameList.end(); ++anIter )
721   {
722     HypothesisData* aData = SMESH::GetHypothesisData( *anIter );
723     if ( isCompatible ( theAlgoData, aData, theHypType )) {
724       theDataList.append( aData );
725       theHyps.append( aData->Label );
726     }
727   }
728 }
729
730 //================================================================================
731 /*!
732  * \brief Gets existing hypotheses or algorithms
733   * \param theDim - specifies dimension of returned hypotheses/algorifms
734   * \param theHypType - specifies whether algorims or hypotheses or additional ones
735   * are retrieved (possible values are in HypType enumeration)
736   * \param theFather - start object for finding ( may be component, mesh, or sub-mesh )
737   * \param theHyps - output list of names.
738   * \param theHypVars - output list of variables.
739   * \param theAlgoData - to select hypos able to be used by this algo (optional)
740  *
741  * Gets existing (i.e. already created) hypotheses or algorithm in accordance with
742  * input parameters
743  */
744 //================================================================================
745 void SMESHGUI_MeshOp::existingHyps( const int theDim,
746                                     const int theHypType,
747                                     _PTR(SObject) theFather,
748                                     QStringList& theHyps,
749                                     THypList& theHypList,
750                                     HypothesisData* theAlgoData)
751 {
752   // Clear hypoheses list
753   theHyps.clear();
754   theHypList.clear();
755
756   if ( !theFather )
757     return;
758
759   const bool isAux  = ( theHypType == AddHyp );
760
761   _PTR(SObject)          aHypRoot;
762   _PTR(GenericAttribute) anAttr;
763   _PTR(AttributeName)    aName;
764   _PTR(AttributeIOR)     anIOR;
765
766   bool isMesh = !_CAST( SComponent, theFather );
767   int aPart = -1;
768   if ( isMesh )
769     aPart = theHypType == Algo ? GLOBAL_ALGO_TAG : GLOBAL_HYPO_TAG;
770   else
771     aPart = theHypType == Algo ? LOCAL_ALGO_TAG : LOCAL_HYPO_TAG;
772
773   if ( theFather->FindSubObject( aPart, aHypRoot ) )
774   {
775     _PTR(ChildIterator) anIter =
776       SMESH::GetActiveStudyDocument()->NewChildIterator( aHypRoot );
777     for (; anIter->More(); anIter->Next() )
778     {
779       _PTR(SObject) anObj = anIter->Value();
780       if ( isMesh ) // i.e. mesh or submesh
781       {
782         _PTR(SObject) aRefObj;
783         if ( anObj->ReferencedObject( aRefObj ) )
784           anObj = aRefObj;
785         else
786           continue;
787       }
788       if ( anObj->FindAttribute( anAttr, "AttributeName" ) )
789       {
790         aName = anAttr;
791         CORBA::Object_var aVar = _CAST(SObject,anObj)->GetObject();
792         if ( !CORBA::is_nil( aVar ) )
793         {
794           SMESH::SMESH_Hypothesis_var aHypVar = SMESH::SMESH_Hypothesis::_narrow( aVar );
795           if ( !aHypVar->_is_nil() )
796           {
797             CORBA::String_var aHypType( aHypVar->GetName() );
798             HypothesisData* aData = SMESH::GetHypothesisData( aHypType );
799             if ( ( theDim == -1 || aData->Dim.contains( theDim ) ) &&
800                  ( isCompatible ( theAlgoData, aData, theHypType )) &&
801                  ( isAux == aData->IsAux ))
802             {
803               std::string aHypName = aName->Value();
804               theHyps.append( aHypName.c_str() );
805               theHypList.append( THypItem( aHypVar, aHypName.c_str() ) );
806             }
807           }
808         }
809       }
810     }
811   }
812 }
813
814 //================================================================================
815 /*!
816  * \brief If create or edit a submesh, return a hypothesis holding parameters used
817  *        to mesh a subshape
818   * \param aHypType - The hypothesis type name
819   * \param aServerLib - Server library name
820   * \param hypData - The structure holding the hypothesis type etc.
821   * \retval SMESH::SMESH_Hypothesis_var - the hypothesis holding parameter values
822  */
823 //================================================================================
824
825 SMESH::SMESH_Hypothesis_var
826 SMESHGUI_MeshOp::getInitParamsHypothesis( const QString& aHypType,
827                                           const QString& aServerLib ) const
828 {
829   if ( aHypType.isEmpty() || aServerLib.isEmpty() )
830     return SMESH::SMESH_Hypothesis::_nil();
831
832   const int nbColonsInMeshEntry = 3;
833   bool isSubMesh = myToCreate ?
834     !myIsMesh :
835     myDlg->selectedObject( SMESHGUI_MeshDlg::Obj ).contains(':') > nbColonsInMeshEntry;
836
837   if ( isSubMesh )
838   {
839     // get mesh and geom object
840     SMESH::SMESH_Mesh_var aMeshVar = SMESH::SMESH_Mesh::_nil();
841     GEOM::GEOM_Object_var aGeomVar = GEOM::GEOM_Object::_nil();
842
843     QString anEntry = myDlg->selectedObject
844       ( myToCreate ? SMESHGUI_MeshDlg::Mesh : SMESHGUI_MeshDlg::Obj );
845     if ( _PTR(SObject) pObj = studyDS()->FindObjectID( anEntry.latin1() ))
846     {
847       CORBA::Object_ptr Obj = _CAST( SObject,pObj )->GetObject();
848       if ( myToCreate ) // mesh and geom may be selected
849       {
850         aMeshVar = SMESH::SMESH_Mesh::_narrow( Obj );
851         anEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
852         if ( _PTR(SObject) pGeom = studyDS()->FindObjectID( anEntry.latin1() ))
853           aGeomVar= GEOM::GEOM_Object::_narrow( _CAST( SObject,pGeom )->GetObject() );
854       }
855       else // edition: sub-mesh may be selected
856       {
857         SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( Obj );
858         if ( !sm->_is_nil() ) {
859           aMeshVar = sm->GetFather();
860           aGeomVar = sm->GetSubShape();
861         }
862       }
863     }
864
865     if ( !aMeshVar->_is_nil() && !aGeomVar->_is_nil() )
866       return SMESHGUI::GetSMESHGen()->GetHypothesisParameterValues( aHypType,
867                                                                     aServerLib,
868                                                                     aMeshVar,
869                                                                     aGeomVar );
870   }
871   return SMESH::SMESH_Hypothesis::_nil();
872 }
873
874 //================================================================================
875 /*!
876  * \Brief Returns tab dimention
877   * \param tab - the tab in the dlg
878   * \param dlg - my dialogue
879   * \retval int - dimention
880  */
881 //================================================================================
882
883 static int getTabDim (const QObject* tab, SMESHGUI_MeshDlg* dlg )
884 {
885   int aDim = -1;
886   for (int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++)
887     if (tab == dlg->tab(i))
888       aDim = i;
889   return aDim;
890 }
891
892 //================================================================================
893 /*!
894  * \brief Create hypothesis
895   * \param theHypType - hypothesis category (main or additional)
896   * \param theIndex - index of type of hypothesis to be cerated
897  *
898  * Specifies dimension of hypothesis to be created (using sender() method),
899  * specifies its type and calls method for hypothesis creation
900  */
901 //================================================================================
902 void SMESHGUI_MeshOp::onCreateHyp( const int theHypType, const int theIndex )
903 {
904   // Specifies dimension of hypothesis to be created
905   int aDim = getTabDim( sender(), myDlg );
906   if (aDim == -1)
907     return;
908
909   // Specifies type of hypothesis to be created
910   THypDataList& dataList = myAvailableHypData[ aDim ][ theHypType ];
911   if (theIndex < 0 || theIndex >= dataList.count())
912     return;
913   QString aHypTypeName = dataList[ theIndex ]->TypeName;
914
915   // Create hypothesis
916   createHypothesis(aDim, theHypType, aHypTypeName);
917 }
918
919 //================================================================================
920 /*!
921  *  Create hypothesis and update dialog.
922  *  \param theDim - dimension of hypothesis to be created
923  *  \param theType - hypothesis category (algorithm, hypothesis, additional hypothesis)
924  *  \param theTypeName - specifies hypothesis to be created
925  */
926 //================================================================================
927 namespace
928 {
929   QString GetUniqueName (const QStringList& theHypNames,
930                          const QString& theName,
931                          size_t theIteration = 1)
932   {
933     QString aName = theName + "_" + QString::number( theIteration );
934     if ( theHypNames.contains( aName ) )
935       return GetUniqueName( theHypNames, theName, ++theIteration );
936     return aName;
937   }
938 }
939
940 void SMESHGUI_MeshOp::createHypothesis (const int theDim,
941                                         const int theType,
942                                         const QString& theTypeName)
943 {
944   // During a hypothesis creation we might need to select some objects.
945   // Main dialog must not update it's own selected objects in this case.
946   dlg()->deactivateAll();
947
948   HypothesisData* aData = SMESH::GetHypothesisData(theTypeName.latin1());
949   if (!aData)
950     return;
951
952   QStringList aHypNames;
953   TDim2Type2HypList::const_iterator aDimIter = myExistingHyps.begin();
954   for( ; aDimIter != myExistingHyps.end(); aDimIter++ ) {
955     const TType2HypList& aType2HypList = aDimIter.data();
956     TType2HypList::const_iterator aTypeIter = aType2HypList.begin();
957     for( ; aTypeIter != aType2HypList.end(); aTypeIter++ ) {
958       const THypList& aHypList = aTypeIter.data();
959       THypList::const_iterator anIter = aHypList.begin();
960       for( ; anIter != aHypList.end(); anIter++ ) {
961         const THypItem& aHypItem = *anIter;
962         const QString& aHypName = aHypItem.second;
963         aHypNames.append(aHypName);
964       }      
965     }    
966   }
967   QString aHypName = GetUniqueName( aHypNames, aData->Label);
968
969   // existing hypos
970   int nbHyp = myExistingHyps[theDim][theType].count();
971
972   QString aClientLibName = aData->ClientLibName;
973   if (aClientLibName == "") {
974     // Call hypothesis creation server method (without GUI)
975     SMESH::CreateHypothesis(theTypeName, aHypName, false);
976   } else {
977     // Get hypotheses creator client (GUI)
978     SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(theTypeName);
979
980     // Create hypothesis
981     if (aCreator) {
982       // When create or edit a submesh, try to initialize a new hypothesis
983       // with values used to mesh a subshape
984       SMESH::SMESH_Hypothesis_var initParamHyp =
985         getInitParamsHypothesis(theTypeName, aData->ServerLibName);
986       myDlg->setEnabled( false );
987       aCreator->create(initParamHyp, aHypName, myDlg);
988       myDlg->setEnabled( true );
989     } else {
990       SMESH::CreateHypothesis(theTypeName, aHypName, false);
991     }
992   }
993
994   _PTR(SComponent) aFather = SMESH::GetActiveStudyDocument()->FindComponent("SMESH");
995
996   HypothesisData* algoData = hypData( theDim, Algo, currentHyp( theDim, Algo ));
997   QStringList aNewHyps;
998   existingHyps(theDim, theType, aFather, aNewHyps, myExistingHyps[theDim][theType], algoData);
999   if (aNewHyps.count() > nbHyp) {
1000     for (int i = nbHyp; i < aNewHyps.count(); i++)
1001       myDlg->tab(theDim)->addHyp(theType, aNewHyps[i]);
1002   }
1003 }
1004
1005 //================================================================================
1006 /*!
1007  * \brief Calls plugin methods for hypothesis editing
1008   * \param theHypType - specifies whether main hypothesis or additional one
1009   * is edited
1010   * \param theIndex - index of existing hypothesis
1011  *
1012  * Calls plugin methods for hypothesis editing
1013  */
1014 //================================================================================
1015 void SMESHGUI_MeshOp::onEditHyp( const int theHypType, const int theIndex )
1016 {
1017   // Speicfies dimension of hypothesis to be created
1018   int aDim = getTabDim( sender(), myDlg );
1019   if (aDim == -1)
1020     return;
1021
1022   const THypList& aList = myExistingHyps[ aDim ][ theHypType ];
1023   if ( theIndex < 0 || theIndex >= aList.count() )
1024     return;
1025   const THypItem& aHypItem = aList[ theIndex ];
1026   SMESH::SMESH_Hypothesis_var aHyp = aHypItem.first;
1027   if ( aHyp->_is_nil() )
1028     return;
1029
1030   CORBA::String_var aTypeName = aHyp->GetName();
1031   SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator( aTypeName );
1032   if ( aCreator ) {
1033     myDlg->setEnabled( false );
1034     aCreator->edit( aHyp.in(), aHypItem.second, dlg() );
1035     myDlg->setEnabled( true );
1036   }
1037 }
1038
1039 //================================================================================
1040 /*!
1041  * \brief access to hypothesis data
1042   * \param theDim - hyp dimension
1043   * \param theHypType - hyp type (Algo,MainHyp or AddHyp)
1044   * \param theIndex - index in the list
1045   * \retval HypothesisData* - result data, may be 0
1046  */
1047 //================================================================================
1048
1049 HypothesisData* SMESHGUI_MeshOp::hypData( const int theDim,
1050                                           const int theHypType,
1051                                           const int theIndex)
1052 {
1053   if ( theDim     > -1 && theDim    <= SMESH::DIM_3D &&
1054        theHypType > -1 && theHypType < NbHypTypes &&
1055        theIndex   > -1 && theIndex   < myAvailableHypData[ theDim ][ theHypType ].count() )
1056     return myAvailableHypData[ theDim ][ theHypType ][ theIndex ];
1057   return 0;
1058 }
1059
1060 //================================================================================
1061 /*!
1062  * \brief Set available algos and hypos according to the selected algorithm
1063   * \param theIndex - algorithm index
1064  */
1065 //================================================================================
1066
1067 void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
1068                                       const int theDim )
1069 {
1070   if ( myIgnoreAlgoSelection )
1071     return;
1072
1073   int aDim = theDim < 0 ? getTabDim( sender(), myDlg ): theDim;
1074   if (aDim == -1)
1075     return;
1076
1077   // find highest available dimension, all algos of this dimension are available for choice
1078   int aTopDim = -1;
1079   for (int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++)
1080     if (isAccessibleDim( i ))
1081       aTopDim = i;
1082   if (aTopDim == -1)
1083     return;
1084
1085   const bool isSubmesh = ( myToCreate ? !myIsMesh : myDlg->isObjectShown( SMESHGUI_MeshDlg::Mesh ));
1086
1087   HypothesisData* algoData = hypData( aDim, Algo, theIndex );
1088   HypothesisData* algoByDim[4];
1089   algoByDim[ aDim ] = algoData;
1090
1091   QStringList anAvailable;
1092   if ( !algoData ) { // all algos becomes available
1093     availableHyps( aDim, Algo, anAvailable, myAvailableHypData[ aDim ][ Algo ]);
1094     myDlg->tab( aDim )->setAvailableHyps( Algo, anAvailable );
1095   }
1096
1097   // check that algorithms of other dimentions are compatible with
1098   // the selected one
1099
1100    // 2 loops: backward and forward from algo dimension
1101   for ( int forward = false; forward <= true; ++forward )
1102   {
1103     int dim = aDim + 1, lastDim = SMESH::DIM_3D, dir = 1;
1104     if ( !forward ) {
1105       dim = aDim - 1; lastDim = SMESH::DIM_0D; dir = -1;
1106     }
1107     HypothesisData* prevAlgo = algoData;
1108     bool noCompatible = false;
1109     for ( ; dim * dir <= lastDim * dir ; dim += dir )
1110     {
1111       if ( !isAccessibleDim( dim ))
1112         continue;
1113       if ( noCompatible ) { // the selected algo has no compatible ones
1114         anAvailable.clear();
1115         myDlg->tab( dim )->setAvailableHyps( Algo, anAvailable );
1116         myAvailableHypData[dim][Algo].clear();
1117         algoByDim[ dim ] = 0;
1118         continue;
1119       }
1120       // get currently selected algo
1121       int algoIndex = currentHyp( dim, Algo );
1122       HypothesisData* curAlgo = hypData( dim, Algo, algoIndex );
1123       if ( curAlgo ) { // some algo selected
1124         if ( !isCompatible( prevAlgo, curAlgo, Algo ))
1125           curAlgo = 0;
1126       }
1127       // set new available algoritms
1128       availableHyps( dim, Algo, anAvailable, myAvailableHypData[dim][Algo], prevAlgo );
1129       HypothesisData* soleCompatible = 0;
1130       if ( anAvailable.count() == 1 )
1131         soleCompatible = myAvailableHypData[dim][Algo][0];
1132       if ( dim == aTopDim && prevAlgo ) // all available algoritms should be selectable any way
1133         availableHyps( dim, Algo, anAvailable, myAvailableHypData[dim][Algo], 0 );
1134       myDlg->tab( dim )->setAvailableHyps( Algo, anAvailable );
1135       noCompatible = anAvailable.isEmpty();
1136
1137       // restore previously selected algo
1138       algoIndex = myAvailableHypData[dim][Algo].findIndex( curAlgo );
1139       if ( !isSubmesh && algoIndex < 0 && soleCompatible && !forward && dim != SMESH::DIM_0D)
1140         // select the sole compatible algo
1141         algoIndex = myAvailableHypData[dim][Algo].findIndex( soleCompatible );
1142       setCurrentHyp( dim, Algo, algoIndex );
1143
1144       // remember current algo
1145       prevAlgo = algoByDim[ dim ] = hypData( dim, Algo, algoIndex );
1146     }
1147   }
1148
1149   // set hypotheses corresponding to the found algoritms
1150
1151   _PTR(SObject) pObj = SMESH::GetActiveStudyDocument()->FindComponent("SMESH");
1152
1153   for ( int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++ )
1154   {
1155     if ( !isAccessibleDim( dim ))
1156       continue;
1157     for ( int type = MainHyp; type < NbHypTypes; type++ )
1158     {
1159       myAvailableHypData[ dim ][ type ].clear();
1160       QStringList anAvailable, anExisting;
1161
1162       HypothesisData* curAlgo = algoByDim[ dim ];
1163       int hypIndex = currentHyp( dim, type );
1164
1165       SMESH::SMESH_Hypothesis_var curHyp;
1166       if ( hypIndex >= 0 && hypIndex < myExistingHyps[ dim ][ type ].count() )
1167         curHyp = myExistingHyps[ dim ][ type ][ hypIndex ].first;
1168
1169       if ( !myToCreate && !curAlgo && !curHyp->_is_nil() ) { // edition, algo not selected
1170         // try to find algo by selected hypothesis in order to keep it selected
1171         bool algoDeselectedByUser = ( theDim < 0 && aDim == dim );
1172         CORBA::String_var curHypType = curHyp->GetName();
1173         if ( !algoDeselectedByUser &&
1174              myObjHyps[ dim ][ type ].count() > 0 &&
1175              curHypType == myObjHyps[ dim ][ type ].first().first->GetName())
1176         {
1177           CORBA::String_var aName = curHyp->GetName();
1178           HypothesisData* hypData = SMESH::GetHypothesisData( aName );
1179           for ( int i = 0 ; i < myAvailableHypData[ dim ][ Algo ].count(); ++i ) {
1180             curAlgo = myAvailableHypData[ dim ][ Algo ][ i ];
1181             if ( curAlgo && hypData && isCompatible( curAlgo, hypData, type ))
1182               break;
1183             else
1184               curAlgo = 0;
1185           }
1186         }
1187       }
1188       // get hyps compatible with curAlgo
1189       if ( curAlgo )
1190       {
1191         // check if a selected hyp is compatible with the curAlgo
1192         if ( !curHyp->_is_nil() ) {
1193           CORBA::String_var aName = curHyp->GetName();
1194           HypothesisData* hypData = SMESH::GetHypothesisData( aName );
1195           if ( !isCompatible( curAlgo, hypData, type ))
1196             curHyp = SMESH::SMESH_Hypothesis::_nil();
1197         }
1198         existingHyps( dim, type, pObj, anExisting, myExistingHyps[ dim ][ type ], curAlgo);
1199         availableHyps( dim, type, anAvailable, myAvailableHypData[ dim ][ type ], curAlgo);
1200       }
1201       // set list of hypotheses
1202       myDlg->tab( dim )->setAvailableHyps( type, anAvailable );
1203       myDlg->tab( dim )->setExistingHyps( type, anExisting );
1204
1205       // set current existing hypothesis
1206       if ( !curHyp->_is_nil() && !anExisting.isEmpty() )
1207         hypIndex = this->find( curHyp, myExistingHyps[ dim ][ type ]);
1208       else
1209         hypIndex = -1;
1210       if ( !isSubmesh && hypIndex < 0 && anExisting.count() == 1 ) {
1211         // none is yet selected => select the sole existing if it is not optional
1212         CORBA::String_var hypTypeName = myExistingHyps[ dim ][ type ].first().first->GetName();
1213         bool isOptional = true;
1214         if ( algoByDim[ dim ] &&
1215              SMESH::IsAvailableHypothesis( algoByDim[ dim ], hypTypeName.in(), isOptional ) &&
1216              !isOptional )
1217           hypIndex = 0;
1218       }
1219       setCurrentHyp( dim, type, hypIndex );
1220     }
1221   }
1222 }
1223
1224 //================================================================================
1225 /*!
1226  * \brief Creates and selects hypothesis of hypotheses set
1227  * \param theSetName - The name of hypotheses set
1228  */
1229 //================================================================================
1230 void SMESHGUI_MeshOp::onHypoSet( const QString& theSetName )
1231 {
1232   HypothesesSet* aHypoSet = SMESH::GetHypothesesSet(theSetName);
1233   if (!aHypoSet) return;
1234
1235   // clear all hyps
1236   for (int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++) {
1237     setCurrentHyp(dim, Algo, -1);
1238     setCurrentHyp(dim, AddHyp, -1);
1239     setCurrentHyp(dim, MainHyp, -1);
1240   }
1241
1242   for (int aHypType = Algo; aHypType < AddHyp; aHypType++) {
1243     bool isAlgo = (aHypType == Algo);
1244
1245     // set hyps from the set
1246     QStringList* aHypoList = isAlgo ? &aHypoSet->AlgoList : &aHypoSet->HypoList;
1247     for (int i = 0, n = aHypoList->count(); i < n; i++) {
1248       const QString& aHypoTypeName = (*aHypoList)[ i ];
1249       HypothesisData* aHypData = SMESH::GetHypothesisData(aHypoTypeName);
1250       if (!aHypData)
1251         continue;
1252
1253       int aDim = aHypData->Dim[0];
1254       // create or/and set
1255       if (isAlgo) {
1256         int index = myAvailableHypData[aDim][Algo].findIndex( aHypData );
1257         if ( index < 0 ) {
1258           QStringList anAvailable;
1259           availableHyps( aDim, Algo, anAvailable, myAvailableHypData[aDim][Algo] );
1260           myDlg->tab( aDim )->setAvailableHyps( Algo, anAvailable );
1261           index = myAvailableHypData[aDim][Algo].findIndex( aHypData );
1262         }
1263         setCurrentHyp( aDim, Algo, index );
1264         onAlgoSelected( index, aDim );
1265       }
1266       else {
1267         bool mainHyp = true;
1268         QStringList anAvailable;
1269         availableHyps( aDim, MainHyp, anAvailable, myAvailableHypData[aDim][MainHyp] );
1270         myDlg->tab( aDim )->setAvailableHyps( MainHyp, anAvailable );
1271         int index = myAvailableHypData[aDim][MainHyp].findIndex( aHypData );
1272         if ( index < 0 ) {
1273           mainHyp = false;
1274           index = myAvailableHypData[aDim][AddHyp].findIndex( aHypData );
1275         }
1276         if (index >= 0)
1277           createHypothesis(aDim, mainHyp ? MainHyp : AddHyp, aHypoTypeName);
1278       }
1279     } // loop on hypos in the set
1280   } // loop on algo/hypo
1281 }
1282
1283 //================================================================================
1284 /*!
1285  * \brief Creates mesh
1286   * \param theMess - Output parameter intended for returning error message
1287   * \retval bool  - TRUE if mesh is created, FALSE otherwise
1288  *
1289  * Creates mesh
1290  */
1291 //================================================================================
1292 bool SMESHGUI_MeshOp::createMesh( QString& theMess )
1293 {
1294   theMess = "";
1295
1296   //QString aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
1297   //QString aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
1298
1299   QStringList aList;
1300   myDlg->selectedObject( SMESHGUI_MeshDlg::Geom, aList );
1301   QStringList::Iterator it = aList.begin();
1302   for(; it!=aList.end(); it++) {
1303
1304     QString aGeomEntry = *it;
1305     _PTR(SObject) pGeom = studyDS()->FindObjectID( aGeomEntry.latin1() );
1306     GEOM::GEOM_Object_var aGeomVar =
1307       GEOM::GEOM_Object::_narrow( _CAST( SObject,pGeom )->GetObject() );
1308
1309     SMESH::SMESH_Gen_var aSMESHGen = SMESHGUI::GetSMESHGen();
1310     if ( aSMESHGen->_is_nil() )
1311       return false;
1312
1313     SUIT_OverrideCursor aWaitCursor;
1314
1315     // create mesh
1316     SMESH::SMESH_Mesh_var aMeshVar = aSMESHGen->CreateMesh( aGeomVar );
1317     if ( aMeshVar->_is_nil() )
1318       return false;
1319     _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshVar.in() );
1320     if ( aMeshSO )
1321       SMESH::SetName( aMeshSO, myDlg->objectText( SMESHGUI_MeshDlg::Obj ).latin1() );
1322
1323     for ( int aDim = SMESH::DIM_0D; aDim <= SMESH::DIM_3D; aDim++ ) {
1324       if ( !isAccessibleDim( aDim )) continue;
1325
1326       // assign hypotheses
1327       for ( int aHypType = MainHyp; aHypType <= AddHyp; aHypType++ ) {
1328         int aHypIndex = currentHyp( aDim, aHypType );
1329         if ( aHypIndex >= 0 && aHypIndex < myExistingHyps[ aDim ][ aHypType ].count() ) {
1330           SMESH::SMESH_Hypothesis_var aHypVar = myExistingHyps[ aDim ][ aHypType ][ aHypIndex ].first;
1331           if ( !aHypVar->_is_nil() )
1332             SMESH::AddHypothesisOnMesh( aMeshVar, aHypVar );
1333         }
1334       }
1335       // find or create algorithm
1336       SMESH::SMESH_Hypothesis_var anAlgoVar = getAlgo( aDim );
1337       if ( !anAlgoVar->_is_nil() )
1338         SMESH::AddHypothesisOnMesh( aMeshVar, anAlgoVar );
1339     }
1340
1341   }
1342   return true;
1343 }
1344
1345 //================================================================================
1346 /*!
1347  * \brief Creates sub-mesh
1348   * \param theMess - Output parameter intended for returning error message
1349   * \retval bool  - TRUE if sub-mesh is created, FALSE otherwise
1350  *
1351  * Creates sub-mesh
1352  */
1353 //================================================================================
1354 bool SMESHGUI_MeshOp::createSubMesh( QString& theMess )
1355 {
1356   theMess = "";
1357
1358   SMESH::SMESH_Gen_var aSMESHGen = SMESHGUI::GetSMESHGen();
1359   if ( aSMESHGen->_is_nil() )
1360     return false;
1361
1362   // get mesh object
1363   QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
1364   _PTR(SObject) pMesh = studyDS()->FindObjectID( aMeshEntry.latin1() );
1365   SMESH::SMESH_Mesh_var aMeshVar =
1366     SMESH::SMESH_Mesh::_narrow( _CAST( SObject,pMesh )->GetObject() );
1367   if (aMeshVar->_is_nil())
1368     return false;
1369
1370   // GEOM shape of the main mesh
1371   GEOM::GEOM_Object_var mainGeom = aMeshVar->GetShapeToMesh();
1372
1373   // Name for the new sub-mesh
1374   QString aName = myDlg->objectText(SMESHGUI_MeshDlg::Obj);
1375
1376   // get geom object
1377   GEOM::GEOM_Object_var aGeomVar;
1378   QStringList aGEOMs;
1379   myDlg->selectedObject(SMESHGUI_MeshDlg::Geom, aGEOMs);
1380   if (aGEOMs.count() == 1)
1381   {
1382     //QString aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
1383     QString aGeomEntry = aGEOMs.first();
1384     _PTR(SObject) pGeom = studyDS()->FindObjectID( aGeomEntry.latin1() );
1385     aGeomVar = GEOM::GEOM_Object::_narrow( _CAST( SObject,pGeom )->GetObject() );
1386   }
1387   else if (aGEOMs.count() > 1)
1388   {
1389     // create a GEOM group
1390     GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen();
1391     _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
1392     if (!geomGen->_is_nil() && aStudy) {
1393       GEOM::GEOM_IGroupOperations_var op =
1394         geomGen->GetIGroupOperations(aStudy->StudyId());
1395       if (!op->_is_nil()) {
1396         // check and add all selected GEOM objects: they must be
1397         // a sub-shapes of the main GEOM and must be of one type
1398         int iSubSh = 0;
1399         TopAbs_ShapeEnum aGroupType = TopAbs_SHAPE;
1400         GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO;
1401         aSeq->length(aGEOMs.count());
1402         QStringList::const_iterator aSubShapesIter = aGEOMs.begin();
1403         for (; aSubShapesIter != aGEOMs.end(); aSubShapesIter++, iSubSh++) {
1404           QString aSubGeomEntry = (*aSubShapesIter);
1405           _PTR(SObject) pSubGeom = studyDS()->FindObjectID(aSubGeomEntry.latin1());
1406           GEOM::GEOM_Object_var aSubGeomVar =
1407             GEOM::GEOM_Object::_narrow(_CAST(SObject,pSubGeom)->GetObject());
1408           TopAbs_ShapeEnum aSubShapeType = (TopAbs_ShapeEnum)aSubGeomVar->GetShapeType();
1409           if (iSubSh == 0) {
1410             aGroupType = aSubShapeType;
1411           } else {
1412             if (aSubShapeType != aGroupType)
1413               aGroupType = TopAbs_SHAPE;
1414           }
1415           aSeq[iSubSh] = aSubGeomVar;
1416         }
1417         // create a group
1418         GEOM::GEOM_Object_var aGroupVar = op->CreateGroup(mainGeom, aGroupType);
1419         op->UnionList(aGroupVar, aSeq);
1420
1421         if (op->IsDone()) {
1422           aGeomVar = aGroupVar;
1423
1424           // publish the GEOM group in study
1425           QString aNewGeomGroupName ("Auto_group_for_");
1426           aNewGeomGroupName += aName;
1427           SALOMEDS::SObject_var aNewGroupSO =
1428             geomGen->AddInStudy(aSMESHGen->GetCurrentStudy(), aGeomVar, aNewGeomGroupName, mainGeom);
1429         }
1430       }
1431     }
1432   }
1433   else {
1434   }
1435   if (aGeomVar->_is_nil())
1436     return false;
1437
1438   SUIT_OverrideCursor aWaitCursor;
1439
1440   // create sub-mesh
1441   SMESH::SMESH_subMesh_var aSubMeshVar = aMeshVar->GetSubMesh( aGeomVar, aName.latin1() );
1442
1443   for ( int aDim = SMESH::DIM_0D; aDim <= SMESH::DIM_3D; aDim++ )
1444   {
1445     if ( !isAccessibleDim( aDim )) continue;
1446
1447     // find or create algorithm
1448     SMESH::SMESH_Hypothesis_var anAlgoVar = getAlgo( aDim );
1449     if ( !anAlgoVar->_is_nil() )
1450       SMESH::AddHypothesisOnSubMesh( aSubMeshVar, anAlgoVar );
1451     // assign hypotheses
1452     for ( int aHypType = MainHyp; aHypType <= AddHyp; aHypType++ )
1453     {
1454       int aHypIndex = currentHyp( aDim, aHypType );
1455       if ( aHypIndex >= 0 && aHypIndex < myExistingHyps[ aDim ][ aHypType ].count() )
1456       {
1457         SMESH::SMESH_Hypothesis_var aHypVar =
1458           myExistingHyps[ aDim ][ aHypType ][ aHypIndex ].first;
1459         if ( !aHypVar->_is_nil() )
1460           SMESH::AddHypothesisOnSubMesh( aSubMeshVar, aHypVar );
1461       }
1462     }
1463   }
1464
1465   // deselect geometry: next submesh should be created on other subshape
1466   myDlg->clearSelection( SMESHGUI_MeshDlg::Geom );
1467   selectObject( _PTR(SObject)() );
1468   selectionDone();
1469
1470   return true;
1471 }
1472
1473 //================================================================================
1474 /*!
1475  * \brief Gets current hypothesis or algorithms
1476   * \param theDim - dimension of hypothesis or algorithm
1477   * \param theHypType - Type of hypothesis (Algo, MainHyp, AddHyp)
1478   * \retval int - current hypothesis or algorithms
1479  *
1480  * Gets current hypothesis or algorithms
1481  */
1482 //================================================================================
1483 int SMESHGUI_MeshOp::currentHyp( const int theDim, const int theHypType ) const
1484 {
1485   return myDlg->tab( theDim )->currentHyp( theHypType ) - 1;
1486 }
1487
1488 //================================================================================
1489 /*!
1490  * \brief Returns true if hypotheses of given dim can be assigned
1491   * \param theDim - hypotheses dimension
1492   * \retval bool - result
1493  */
1494 //================================================================================
1495 bool SMESHGUI_MeshOp::isAccessibleDim( const int theDim ) const
1496 {
1497   return myDlg->tab( theDim )->isEnabled();
1498 }
1499
1500 //================================================================================
1501 /*!
1502  * \brief Sets current hypothesis or algorithms
1503   * \param theDim - dimension of hypothesis or algorithm
1504   * \param theHypType - Type of hypothesis (Algo, MainHyp, AddHyp)
1505   * \param theIndex - Index of hypothesis
1506  *
1507  * Gets current hypothesis or algorithms
1508  */
1509 //================================================================================
1510 void SMESHGUI_MeshOp::setCurrentHyp( const int theDim,
1511                                      const int theHypType,
1512                                      const int theIndex )
1513 {
1514   myIgnoreAlgoSelection = true;
1515   myDlg->tab( theDim )->setCurrentHyp( theHypType, theIndex + 1 );
1516   myIgnoreAlgoSelection = false;
1517 }
1518
1519 //================================================================================
1520 /*!
1521  * \brief Generates default and sets mesh/submesh name
1522  *
1523  * Generates and sets default mesh/submesh name(Mesh_1, Mesh_2, etc.)
1524  */
1525 //================================================================================
1526 void SMESHGUI_MeshOp::setDefaultName() const
1527 {
1528   QString aResName;
1529
1530   _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
1531   int i = 1;
1532   QString aPrefix = tr( myIsMesh ? "SMESH_OBJECT_MESH" : "SMESH_SUBMESH" ) + "_";
1533   _PTR(SObject) anObj;
1534   do
1535   {
1536     aResName = aPrefix + QString::number( i++ );
1537     anObj = aStudy->FindObject( aResName.latin1() );
1538   }
1539   while ( anObj );
1540
1541   QLineEdit* aControl = ( QLineEdit* )myDlg->objectWg(
1542     SMESHGUI_MeshDlg::Obj, SMESHGUI_MeshDlg::Control );
1543   aControl->setText( aResName );
1544 }
1545
1546 //================================================================================
1547 /*!
1548  * \brief Gets algorithm or creates it if necessary
1549   * \param theDim - specifies dimension of returned hypotheses/algorifms
1550   * \retval SMESH::SMESH_Hypothesis_var - algorithm
1551  *
1552  * Gets algorithm or creates it if necessary
1553  */
1554 //================================================================================
1555 SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim )
1556 {
1557   SMESH::SMESH_Hypothesis_var anAlgoVar;
1558
1559   // get type of the selected algo
1560   int aHypIndex = currentHyp( theDim, Algo );
1561   THypDataList& dataList = myAvailableHypData[ theDim ][ Algo ];
1562   if ( aHypIndex < 0 || aHypIndex >= dataList.count())
1563     return anAlgoVar;
1564   QString aHypName = dataList[ aHypIndex ]->TypeName;
1565
1566   // get existing algoritms
1567   _PTR(SObject) pObj = SMESH::GetActiveStudyDocument()->FindComponent("SMESH");
1568   QStringList tmp;
1569   existingHyps( theDim, Algo, pObj, tmp, myExistingHyps[ theDim ][ Algo ]);
1570
1571   // look for anexisting algo of such a type
1572   THypList& aHypVarList = myExistingHyps[ theDim ][ Algo ];
1573   THypList::iterator anIter = aHypVarList.begin();
1574   for ( ; anIter != aHypVarList.end(); anIter++ )
1575   {
1576     SMESH::SMESH_Hypothesis_var aHypVar = (*anIter).first;
1577     CORBA::String_var aName = aHypVar->GetName();
1578     if ( !aHypVar->_is_nil() && aHypName == aName )
1579     {
1580       anAlgoVar = aHypVar;
1581       break;
1582     }
1583   }
1584
1585   if (anAlgoVar->_is_nil()) {
1586     HypothesisData* aHypData = SMESH::GetHypothesisData( aHypName );
1587     if (aHypData) {
1588       QString aClientLibName = aHypData->ClientLibName;
1589       if (aClientLibName == "") {
1590         // Call hypothesis creation server method (without GUI)
1591         SMESH::CreateHypothesis(aHypName, aHypData->Label, true);
1592       } else {
1593         // Get hypotheses creator client (GUI)
1594         SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(aHypName);
1595
1596         // Create algorithm
1597         if (aCreator)
1598           aCreator->create(true, aHypName, myDlg);
1599         else
1600           SMESH::CreateHypothesis(aHypName, aHypData->Label, true);
1601       }
1602       QStringList tmpList;
1603       _PTR(SComponent) aFather = SMESH::GetActiveStudyDocument()->FindComponent( "SMESH" );
1604       existingHyps( theDim, Algo, aFather, tmpList, myExistingHyps[ theDim ][ Algo ] );
1605     }
1606
1607     THypList& aNewHypVarList = myExistingHyps[ theDim ][ Algo ];
1608     for ( anIter = aNewHypVarList.begin(); anIter != aNewHypVarList.end(); ++anIter )
1609     {
1610       SMESH::SMESH_Hypothesis_var aHypVar = (*anIter).first;
1611       CORBA::String_var aName = aHypVar->GetName();
1612       if ( !aHypVar->_is_nil() && aHypName == aName )
1613       {
1614         anAlgoVar = aHypVar;
1615         break;
1616       }
1617     }
1618   }
1619
1620   return anAlgoVar._retn();
1621 }
1622
1623 //================================================================================
1624 /*!
1625  * \brief Reads parameters of edited mesh and assigns them to the dialog
1626  *
1627  * Reads parameters of edited mesh and assigns them to the dialog (called when
1628  * mesh is edited only)
1629  */
1630 //================================================================================
1631 void SMESHGUI_MeshOp::readMesh()
1632 {
1633   QString anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
1634   _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.latin1() );
1635   if ( !pObj )
1636     return;
1637
1638   if( myIsOnGeometry ) {  
1639     // Get name of mesh if current object is sub-mesh
1640     SMESH::SMESH_subMesh_var aSubMeshVar =
1641       SMESH::SMESH_subMesh::_narrow( _CAST( SObject,pObj )->GetObject() );
1642     if ( !aSubMeshVar->_is_nil() ) 
1643     {
1644       SMESH::SMESH_Mesh_var aMeshVar =  aSubMeshVar->GetFather();
1645       if ( !aMeshVar->_is_nil() )
1646       {
1647         _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshVar );
1648         QString aMeshName = name( aMeshSO );
1649         myDlg->setObjectText( SMESHGUI_MeshDlg::Mesh, aMeshName );
1650       }
1651     }
1652     
1653     // Get name of geometry object
1654     GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj );
1655     if ( !aGeomVar->_is_nil() )
1656     {
1657       _PTR(SObject) aGeomSO = studyDS()->FindObjectID( aGeomVar->GetStudyEntry() );
1658       QString aShapeName = name( aGeomSO );
1659       myDlg->setObjectText( SMESHGUI_MeshDlg::Geom, aShapeName );
1660     }
1661   }
1662
1663   // Get hypotheses and algorithms assigned to the mesh/sub-mesh
1664   QStringList anExisting;
1665   const int aDim = ( myIsOnGeometry ) ? SMESH::DIM_0D : SMESH::DIM_3D;
1666   for ( int dim = aDim; dim <= SMESH::DIM_3D; dim++ )
1667   {
1668     // get algorithm
1669     existingHyps( dim, Algo, pObj, anExisting, myObjHyps[ dim ][ Algo ] );
1670     // find algo index among available ones
1671     int aHypIndex = -1;
1672     if ( myObjHyps[ dim ][ Algo ].count() > 0 )
1673     {
1674       SMESH::SMESH_Hypothesis_var aVar = myObjHyps[ dim ][ Algo ].first().first;
1675       CORBA::String_var aHypTypeName = aVar->GetName();
1676       HypothesisData* algoData = SMESH::GetHypothesisData( aHypTypeName );
1677       aHypIndex = myAvailableHypData[ dim ][ Algo ].findIndex ( algoData );
1678 //       if ( aHypIndex < 0 && algoData ) {
1679 //         // assigned algo is incompatible with other algorithms
1680 //         myAvailableHypData[ dim ][ Algo ].push_back( algoData );
1681 //         aHypIndex = myAvailableHypData[ dim ][ hypType ].count() - 1;
1682 //       }
1683     }
1684     setCurrentHyp( dim, Algo, aHypIndex );
1685     // set existing and available hypothesis according to the selected algo
1686     onAlgoSelected( aHypIndex, dim );
1687   }
1688
1689   // get hypotheses
1690   bool hypWithoutAlgo = false;
1691   for ( int dim = aDim; dim <= SMESH::DIM_3D; dim++ )
1692   {
1693     for ( int hypType = MainHyp; hypType <= AddHyp; hypType++ )
1694     {
1695       // get hypotheses
1696       existingHyps( dim, hypType, pObj, anExisting, myObjHyps[ dim ][ hypType ] );
1697       // find index of requered hypothesis among existing ones for this dimension and type
1698       int aHypIndex = -1;
1699       if ( myObjHyps[ dim ][ hypType ].count() > 0 ) {
1700         aHypIndex = find( myObjHyps[ dim ][ hypType ].first().first,
1701                           myExistingHyps[ dim ][ hypType ] );
1702         if ( aHypIndex < 0 ) {
1703           // assigned hypothesis is incompatible with the algorithm
1704           if ( currentHyp( dim, Algo ) < 0 )
1705           { // none algo selected; it is edition for sure, of submesh maybe
1706             hypWithoutAlgo = true;
1707             myExistingHyps[ dim ][ hypType ].push_back( myObjHyps[ dim ][ hypType ].first() );
1708             aHypIndex = myExistingHyps[ dim ][ hypType ].count() - 1;
1709             myDlg->tab( dim )->setExistingHyps( hypType, anExisting );
1710           }
1711         }
1712       }
1713       setCurrentHyp( dim, hypType, aHypIndex );
1714     }
1715   }
1716   // make available other hyps of same type as one without algo
1717   if ( hypWithoutAlgo )
1718     onAlgoSelected( currentHyp( 0, Algo ), 0 );
1719 }
1720
1721 //================================================================================
1722 /*!
1723  * \brief Gets name of object
1724   * \param theSO - SObject
1725   * \retval QString - name of object
1726  *
1727  * Gets name of object
1728  */
1729 //================================================================================
1730 QString SMESHGUI_MeshOp::name( _PTR(SObject) theSO ) const
1731 {
1732   QString aResName;
1733   if ( theSO )
1734   {
1735     _PTR(GenericAttribute) anAttr;
1736     _PTR(AttributeName)    aNameAttr;
1737     if ( theSO->FindAttribute( anAttr, "AttributeName" ) )
1738     {
1739       aNameAttr = anAttr;
1740       aResName = aNameAttr->Value().c_str();
1741     }
1742   }
1743   return aResName;
1744 }
1745
1746 //================================================================================
1747 /*!
1748  * \brief Finds hypothesis in input list
1749   * \param theHyp - hypothesis to be found
1750   * \param theHypList - input list of hypotheses
1751   * \retval int - index of hypothesis or -1 if it is not found
1752  *
1753  * Finds position of hypothesis in input list
1754  */
1755 //================================================================================
1756 int SMESHGUI_MeshOp::find( const SMESH::SMESH_Hypothesis_var& theHyp,
1757                            const THypList& theHypList ) const
1758 {
1759   int aRes = -1;
1760   if ( !theHyp->_is_nil() )
1761   {
1762     int i = 0;
1763     THypList::const_iterator anIter = theHypList.begin();
1764     for ( ; anIter != theHypList.end(); ++ anIter )
1765     {
1766       if ( theHyp->_is_equivalent( (*anIter).first ) )
1767       {
1768         aRes = i;
1769         break;
1770       }
1771       i++;
1772     }
1773   }
1774   return aRes;
1775 }
1776
1777 //================================================================================
1778 /*!
1779  * \brief Edits mesh or sub-mesh
1780   * \param theMess - Output parameter intended for returning error message
1781   * \retval bool  - TRUE if mesh is edited succesfully, FALSE otherwise
1782  *
1783  * Assigns new name hypotheses and algoriths to the mesh or sub-mesh
1784  */
1785 //================================================================================
1786 bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess )
1787 {
1788   theMess = "";
1789
1790   SMESH::SMESH_Gen_var aSMESHGen = SMESHGUI::GetSMESHGen();
1791   if ( aSMESHGen->_is_nil() )
1792     return false;
1793
1794   QString anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
1795   _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.latin1() );
1796   if ( !pObj )
1797     return false;
1798
1799   SUIT_OverrideCursor aWaitCursor;
1800
1801   // Set new name
1802   QString aName = myDlg->objectText( SMESHGUI_MeshDlg::Obj );
1803   SMESH::SetName( pObj, aName.latin1() );
1804   int aDim = ( myIsOnGeometry ) ? SMESH::DIM_0D : SMESH::DIM_3D;
1805
1806   // First, remove old algos in order to avoid messages on algorithm hiding
1807   for ( int dim = aDim; dim <= SMESH::DIM_3D; dim++ )
1808   {
1809     if ( isAccessibleDim( dim ) && myObjHyps[ dim ][ Algo ].count() > 0 )
1810     {
1811       SMESH::SMESH_Hypothesis_var anOldAlgo = myObjHyps[ dim ][ Algo ].first().first;
1812       CORBA::String_var anOldName = anOldAlgo->GetName();
1813       SMESH::SMESH_Hypothesis_var anAlgoVar = getAlgo( dim );
1814       //      CORBA::String_var anAlgoName = anAlgoVar->GetName();
1815       if ( anAlgoVar->_is_nil() || // no new algo selected or
1816            strcmp(anOldName.in(), anAlgoVar->GetName()) ) // algo change
1817       {
1818         // remove old algorithm
1819         SMESH::RemoveHypothesisOrAlgorithmOnMesh ( pObj, myObjHyps[ dim ][ Algo ].first().first );
1820         myObjHyps[ dim ][ Algo ].clear();
1821       }
1822     }
1823   }
1824
1825   // Assign new algorithms and hypotheses
1826   for ( int dim = aDim; dim <= SMESH::DIM_3D; dim++ )
1827   {
1828     if ( !isAccessibleDim( dim )) continue;
1829
1830     // find or create algorithm
1831     SMESH::SMESH_Hypothesis_var anAlgoVar = getAlgo( dim );
1832
1833     // assign new algorithm
1834     if ( !anAlgoVar->_is_nil() && // some algo selected and
1835          myObjHyps[ dim ][ Algo ].count() == 0 ) // no algo assigned
1836     {
1837       SALOMEDS_SObject* aSObject = _CAST(SObject, pObj);
1838       CORBA::Object_var anObject = aSObject->GetObject();
1839       SMESH::SMESH_Mesh_var aMeshVar = SMESH::SMESH_Mesh::_narrow( anObject );
1840       bool isMesh = !aMeshVar->_is_nil();
1841       if ( isMesh ) {
1842         SMESH::AddHypothesisOnMesh( aMeshVar, anAlgoVar );
1843       } else {
1844         SMESH::SMESH_subMesh_var aVar =
1845           SMESH::SMESH_subMesh::_narrow( _CAST(SObject,pObj)->GetObject() );
1846         if ( !aVar->_is_nil() )
1847           SMESH::AddHypothesisOnSubMesh( aVar, anAlgoVar );
1848       }
1849       myObjHyps[ dim ][ Algo ].append( THypItem( anAlgoVar, aName) );
1850     }
1851
1852     // assign hypotheses
1853     for ( int hypType = MainHyp; hypType <= AddHyp; hypType++ )
1854     {
1855       int aNewHypIndex = currentHyp( dim, hypType );
1856       int anOldHypIndex = -1;
1857
1858       // remove old hypotheses
1859       if ( myObjHyps[ dim ][ hypType ].count() > 0 )
1860       {
1861         anOldHypIndex = find( myObjHyps[ dim ][ hypType ].first().first ,
1862                               myExistingHyps[ dim ][ hypType ] );
1863         if ( aNewHypIndex != anOldHypIndex || // different hyps
1864              anOldHypIndex == -1 )            // hyps of different algos
1865         {
1866           SMESH::RemoveHypothesisOrAlgorithmOnMesh
1867             ( pObj, myObjHyps[ dim ][ hypType ].first().first );
1868           myObjHyps[ dim ][ hypType ].clear();
1869         }
1870       }
1871
1872       // assign new hypotheses
1873       if ( aNewHypIndex != anOldHypIndex && aNewHypIndex != -1 )
1874       {
1875         SMESH::SMESH_Mesh_var aMeshVar =
1876           SMESH::SMESH_Mesh::_narrow( _CAST(SObject,pObj)->GetObject() );
1877         bool isMesh = !aMeshVar->_is_nil();
1878         if ( isMesh )
1879         {
1880           SMESH::AddHypothesisOnMesh
1881             (aMeshVar, myExistingHyps[ dim ][ hypType ][ aNewHypIndex ].first );
1882         }
1883         else
1884         {
1885           SMESH::SMESH_subMesh_var aVar =
1886             SMESH::SMESH_subMesh::_narrow( _CAST(SObject,pObj)->GetObject() );
1887           if ( !aVar->_is_nil() )
1888             SMESH::AddHypothesisOnSubMesh
1889               ( aVar, myExistingHyps[ dim ][ hypType ][ aNewHypIndex ].first );
1890         }
1891       }
1892       // reread all hypotheses of mesh if necessary
1893       QStringList anExisting;
1894       existingHyps( dim, hypType, pObj, anExisting, myObjHyps[ dim ][ hypType ] );
1895     }
1896   }
1897
1898   return true;
1899 }
1900
1901 //================================================================================
1902 /*!
1903  * \brief Verifies whether given operator is valid for this one
1904   * \param theOtherOp - other operation
1905   * \return Returns TRUE if the given operator is valid for this one, FALSE otherwise
1906 *
1907 * method redefined from base class verifies whether given operator is valid for
1908 * this one (i.e. can be started "above" this operator). In current implementation method
1909 * retuns false if theOtherOp operation is not intended for deleting objects or mesh
1910 * elements.
1911 */
1912 //================================================================================
1913 bool SMESHGUI_MeshOp::isValid( SUIT_Operation* theOp ) const
1914 {
1915   return SMESHGUI_Operation::isValid( theOp ) && !theOp->inherits( "SMESHGUI_MeshOp" );
1916 }
1917
1918 //================================================================================
1919 /*!
1920  * \brief SLOT. Is called when the user selects a way of geometry selection
1921   * \param theByMesh - true if the user wants to find geometry by mesh element
1922  */
1923 //================================================================================
1924
1925 void SMESHGUI_MeshOp::onGeomSelectionByMesh( bool theByMesh )
1926 {
1927   if ( theByMesh ) {
1928     if ( !myShapeByMeshOp ) {
1929       myShapeByMeshOp = new SMESHGUI_ShapeByMeshOp();
1930       connect(myShapeByMeshOp, SIGNAL(committed(SUIT_Operation*)),
1931               SLOT(onPublishShapeByMeshDlg(SUIT_Operation*)));
1932       connect(myShapeByMeshOp, SIGNAL(aborted(SUIT_Operation*)),
1933               SLOT(onCloseShapeByMeshDlg(SUIT_Operation*)));
1934     }
1935     // set mesh object to SMESHGUI_ShapeByMeshOp and start it
1936     QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
1937     if ( _PTR(SObject) pMesh = studyDS()->FindObjectID( aMeshEntry.latin1() )) {
1938       SMESH::SMESH_Mesh_var aMeshVar =
1939         SMESH::SMESH_Mesh::_narrow( _CAST( SObject,pMesh )->GetObject() );
1940       if ( !aMeshVar->_is_nil() ) {
1941         myDlg->hide(); // stop processing selection
1942         myShapeByMeshOp->setModule( getSMESHGUI() );
1943         myShapeByMeshOp->setStudy( 0 ); // it's really necessary
1944         myShapeByMeshOp->SetMesh( aMeshVar );
1945         myShapeByMeshOp->start();
1946       }
1947     }
1948   }
1949 }
1950
1951 //================================================================================
1952 /*!
1953  * \brief SLOT. Is called when Ok is pressed in SMESHGUI_ShapeByMeshDlg
1954  */
1955 //================================================================================
1956
1957 void SMESHGUI_MeshOp::onPublishShapeByMeshDlg(SUIT_Operation* op)
1958 {
1959   if ( myShapeByMeshOp == op ) {
1960     SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser(); //MZN: 24.11.2006  IPAL13980 - Object Browser update added
1961     myDlg->show();
1962     // Select a found geometry object
1963     GEOM::GEOM_Object_var aGeomVar = myShapeByMeshOp->GetShape();
1964     if ( !aGeomVar->_is_nil() )
1965     {
1966       QString ID = aGeomVar->GetStudyEntry();
1967       if ( _PTR(SObject) aGeomSO = studyDS()->FindObjectID( ID.latin1() )) {
1968         selectObject( aGeomSO );
1969         selectionDone();
1970       }
1971     }
1972   }
1973 }
1974
1975 //================================================================================
1976 /*!
1977  * \brief SLOT. Is called when Close is pressed in SMESHGUI_ShapeByMeshDlg
1978  */
1979 //================================================================================
1980
1981 void SMESHGUI_MeshOp::onCloseShapeByMeshDlg(SUIT_Operation* op)
1982 {
1983   if ( myShapeByMeshOp == op && myDlg ) {
1984     myDlg->show();
1985   }
1986 }
1987
1988 //================================================================================
1989 /*!
1990  * \brief Selects a SObject
1991   * \param theSObj - the SObject to select
1992  */
1993 //================================================================================
1994
1995 void SMESHGUI_MeshOp::selectObject( _PTR(SObject) theSObj ) const
1996 {
1997   if ( LightApp_SelectionMgr* sm = selectionMgr() ) {
1998     SALOME_ListIO anIOList;
1999     if ( theSObj ) {
2000       Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject
2001         ( theSObj->GetID().c_str(), "SMESH", theSObj->GetName().c_str() );
2002       anIOList.Append( anIO );
2003     }
2004     sm->setSelectedObjects( anIOList, false );
2005   }
2006 }