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