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