Salome HOME
e001bea8eb89673236448ffb97fed305c25044fa
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_MeshOp.cxx
1 /**
2 *  SMESH SMESHGUI
3 *
4 *  Copyright (C) 2005  CEA/DEN, EDF R&D
5 *
6 *
7 *
8 *  File   : SMESHGUI_MeshOp.h
9 *  Author : Sergey LITONIN
10 *  Module : SMESHGUI
11 */
12
13 #include "SMESHGUI_MeshOp.h"
14 #include "SMESHGUI_MeshDlg.h"
15 #include "SMESH_TypeFilter.hxx"
16 #include "SMESHGUI.h"
17
18 #include "SMESHGUI_HypothesesUtils.h"
19 #include "SMESHGUI_Hypotheses.h"
20 #include "SMESHGUI_Utils.h"
21 #include "SMESHGUI_GEOMGenUtils.h"
22
23 #include <SMESH_TypeFilter.hxx>
24 #include <SMESH_NumberFilter.hxx>
25
26 #include <GEOM_SelectionFilter.h>
27
28 #include <SalomeApp_Tools.h>
29 #include <SALOMEDSClient_Study.hxx>
30 #include <SALOMEDSClient_AttributeIOR.hxx>
31 #include <SALOMEDSClient_AttributeName.hxx>
32 #include <SALOMEDS_SComponent.hxx>
33
34 #include <SalomeApp_SelectionMgr.h>
35 #include <SalomeApp_UpdateFlags.h>
36 #include <SUIT_MessageBox.h>
37 #include <SUIT_Desktop.h>
38 #include <SUIT_OverrideCursor.h>
39
40 #include <utilities.h>
41
42 #include <qstringlist.h>
43 #include <qlineedit.h>
44
45 #include <SALOMEDS_SObject.hxx>
46
47 #define DEB_SLN
48
49 //================================================================================
50 /*!
51  * \brief Constructor
52   * \param theToCreate - if this parameter is true then operation is used for creation,
53   * for editing otherwise
54  *
55  * Initialize operation
56 */
57 //================================================================================
58 SMESHGUI_MeshOp::SMESHGUI_MeshOp( const bool theToCreate, const bool theIsMesh )
59 : SMESHGUI_SelectionOp(),
60   myToCreate( theToCreate ),
61   myIsMesh( theIsMesh ),
62   myDlg( 0 )
63 {
64 }
65
66 //================================================================================
67 /*!
68  * \brief Destructor
69 */
70 //================================================================================
71 SMESHGUI_MeshOp::~SMESHGUI_MeshOp()
72 {
73   if( myDlg )
74     delete myDlg;
75 }
76
77 //================================================================================
78 /*!
79  * \brief Gets dialog of this operation
80   * \retval SalomeApp_Dialog* - pointer to dialog of this operation
81 */
82 //================================================================================
83 SalomeApp_Dialog* SMESHGUI_MeshOp::dlg() const
84 {
85   return myDlg;
86 }
87
88 //================================================================================
89 /*!
90  * \brief Creates or edits mesh
91   * \retval bool - TRUE if operation is performed successfully, FALSE otherwise
92  *
93  * Virtual slot redefined from the base class called when "Apply" button is clicked
94  * creates or edits mesh
95  */
96 //================================================================================
97 bool SMESHGUI_MeshOp::onApply()
98 {
99   if( isStudyLocked() )
100     return false;
101
102   QString aMess;
103   if ( !isValid( aMess ) )
104   {
105     if ( aMess != "" )
106       SUIT_MessageBox::warn1( myDlg,
107         tr( "SMESH_WRN_WARNING" ), aMess, tr( "SMESH_BUT_OK" ) );
108     return false;
109   }
110
111   bool aResult = false;
112   aMess = "";
113   try
114   {
115     if ( myToCreate && myIsMesh )
116       aResult = createMesh( aMess );
117     if ( myToCreate && !myIsMesh )
118       aResult = createSubMesh( aMess );
119     else if ( !myToCreate )
120       aResult = editMeshOrSubMesh( aMess );
121     if ( aResult )
122       update( UF_ObjBrowser | UF_Model );
123   }
124   catch ( const SALOME::SALOME_Exception& S_ex )
125   {
126     SalomeApp_Tools::QtCatchCorbaException( S_ex );
127     aResult = false;
128   }
129   catch ( ... )
130   {
131     aResult = false;
132   }
133
134   if ( aResult )
135   {
136     if ( myToCreate )
137       setDefaultName();
138   }
139   else
140   {
141     if ( aMess == "" )
142       aMess = tr( "SMESH_OPERATION_FAILED" );
143     SUIT_MessageBox::warn1( myDlg,
144       tr( "SMESH_ERROR" ), aMess, tr( "SMESH_BUT_OK" ) );
145   }
146
147   return aResult;
148 }
149
150 //================================================================================
151 /*!
152  * \brief Creates dialog if necessary and shows it
153  *
154  * Virtual method redefined from base class called when operation is started creates
155  * dialog if necessary and shows it, activates selection
156  */
157 //================================================================================
158 void SMESHGUI_MeshOp::startOperation()
159 {
160   if( !myDlg )
161   {
162     myDlg = new SMESHGUI_MeshDlg( myToCreate, myIsMesh );
163     for ( int i = SMESH::DIM_1D; i <= SMESH::DIM_3D; i++ )
164     {
165       connect( myDlg->tab( i ), SIGNAL( createHyp( const int, const int ) ),
166               this, SLOT( onCreateHyp( const int, const int) ) );
167       connect( myDlg->tab( i ), SIGNAL( editHyp( const int, const int ) ),
168               this, SLOT( onEditHyp( const int, const int) ) );
169     }
170   }
171   SMESHGUI_SelectionOp::startOperation();
172
173   // iterate through dimensions and get available and existing algoritms and hypotheses,
174   // set them to the dialog
175   int i, j;
176   _PTR(SComponent) aFather = SMESH::GetActiveStudyDocument()->FindComponent( "SMESH" );
177   for ( i = SMESH::DIM_1D; i <= SMESH::DIM_3D; i++ )
178   {
179     SMESHGUI_MeshTab* aTab = myDlg->tab( i );
180     QStringList anAvailable, anExisting;
181     for ( j = Algo; j <= AddHyp; j++ )
182     {
183       availableHyps( i, j, anAvailable );
184       existingHyps( i, j, aFather, anExisting, myExistingHyps[ i ][ j ] );
185
186       aTab->setAvailableHyps( j, anAvailable );
187       aTab->setExistingHyps( j, anExisting );
188     }
189   }
190   if ( myToCreate )
191   {
192     setDefaultName();
193     myDlg->activateObject( myIsMesh ? SMESHGUI_MeshDlg::Geom : SMESHGUI_MeshDlg::Mesh );
194   }
195   else
196     myDlg->activateObject( SMESHGUI_MeshDlg::Obj );
197
198   selectionDone();
199
200   myDlg->setCurrentTab( SMESH::DIM_1D );
201   myDlg->show();
202 }
203
204 //================================================================================
205 /*!
206  * \brief Creates selection filter
207   * \param theId - identifier of current selection widget
208   * \retval SUIT_SelectionFilter* - pointer to the created filter or null
209  *
210  * Creates selection filter in accordance with identifier of current selection widget
211  */
212 //================================================================================
213 SUIT_SelectionFilter* SMESHGUI_MeshOp::createFilter( const int theId ) const
214 {
215   if ( theId == SMESHGUI_MeshDlg::Geom )
216   {
217 //     TColStd_MapOfInteger allTypesMap;
218 //     for ( int i = 0; i < 10; i++ )
219 //       allTypesMap.Add( i );
220 //     return new SMESH_NumberFilter( "GEOM", TopAbs_SHAPE, 0, allTypesMap );
221     return new GEOM_SelectionFilter( (SalomeApp_Study*)study(), true );
222   }
223   else if ( theId == SMESHGUI_MeshDlg::Obj && !myToCreate )
224     return new SMESH_TypeFilter( MESHorSUBMESH );
225   else if ( theId == SMESHGUI_MeshDlg::Mesh )
226     return new SMESH_TypeFilter( MESH );
227   else
228     return 0;
229 }
230
231 //================================================================================
232 /*!
233  * \brief Updates dialog's look and feel
234  *
235  * Virtual method redefined from the base class updates dialog's look and feel
236  */
237 //================================================================================
238 void SMESHGUI_MeshOp::selectionDone()
239 {
240   SMESHGUI_SelectionOp::selectionDone();
241
242   if ( !myToCreate )
243   {
244     try
245     {
246       QString anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
247       _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.latin1() );
248       if ( pObj != 0 )
249       {
250         SMESH::SMESH_subMesh_var aVar =
251           SMESH::SMESH_subMesh::_narrow( _CAST( SObject,pObj )->GetObject() );
252         myDlg->setObjectShown( SMESHGUI_MeshDlg::Mesh, !aVar->_is_nil() );
253         myDlg->objectWg( SMESHGUI_MeshDlg::Mesh, SMESHGUI_MeshDlg::Btn )->hide();
254         myDlg->updateGeometry();
255         myDlg->adjustSize();
256         readMesh();
257       }
258       else
259         myDlg->reset();
260     }
261     catch ( const SALOME::SALOME_Exception& S_ex )
262     {
263       SalomeApp_Tools::QtCatchCorbaException( S_ex );
264     }
265     catch ( ... )
266     {
267     }
268   }
269 }
270
271 //================================================================================
272 /*!
273  * \brief Verifies validity of input data
274   * \param theMess - Output parameter intended for returning error message
275   * \retval bool  - TRUE if input data is valid, false otherwise
276  *
277  * Verifies validity of input data. This method is called when "Apply" or "OK" button
278  * is pressed before mesh creation or editing.
279  */
280 //================================================================================
281 bool SMESHGUI_MeshOp::isValid( QString& theMess ) const
282 {
283   // Selected object to be  edited
284   if ( !myToCreate && myDlg->selectedObject( SMESHGUI_MeshDlg::Obj ) == "" )
285   {
286     theMess = tr( "THERE_IS_NO_OBJECT_FOR_EDITING" );
287     return false;
288   }
289
290   // Name
291   QString aMeshName = myDlg->objectText( SMESHGUI_MeshDlg::Obj );
292   aMeshName = aMeshName.stripWhiteSpace();
293   if ( aMeshName == "" )
294   {
295     theMess = myIsMesh ? tr( "NAME_OF_MESH_IS_EMPTY" ) : tr( "NAME_OF_SUBMESH_IS_EMPTY" );
296     return false;
297   }
298
299   // Geom
300   if ( myToCreate )
301   {
302     QString aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
303     if ( aGeomEntry == "" )
304     {
305       theMess = tr( "GEOMETRY_OBJECT_IS_NOT_DEFINED" );
306       return false;
307     }
308     _PTR(SObject) pGeom = studyDS()->FindObjectID( aGeomEntry.latin1() );
309     if ( !pGeom || GEOM::GEOM_Object::_narrow( _CAST( SObject,pGeom )->GetObject() )->_is_nil() )
310     {
311       theMess = tr( "GEOMETRY_OBJECT_IS_NULL" );
312       return false;
313     }
314
315     // Mesh
316     if ( !myIsMesh ) // i.e sub-mesh creation,
317     {
318       QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
319       if ( aMeshEntry == "" )
320       {
321         theMess = tr( "MESH_IS_NOT_DEFINED" );
322         return false;
323       }
324       _PTR(SObject) pMesh = studyDS()->FindObjectID( aMeshEntry.latin1() );
325       if ( !pMesh || SMESH::SMESH_Mesh::_narrow( _CAST( SObject,pMesh )->GetObject() )->_is_nil() )
326       {
327         theMess = tr( "MESH_IS_NULL" );
328         return false;
329       }
330     }
331   }
332   return true;
333 }
334
335 //================================================================================
336 /*!
337  * \brief Gets available hypotheses or algorithms
338   * \param theDim - specifies dimension of returned hypotheses/algorifms
339   * \param theHypType - specifies whether algorims or hypotheses or additional ones
340   * are retrieved (possible values are in HypType enumeration)
341   * \param theHyps - Output list of hypotheses' names
342  *
343  * Gets available hypotheses or algorithm in accordance with input parameters
344  */
345 //================================================================================
346 void SMESHGUI_MeshOp::availableHyps( const int theDim,
347                                      const int theHypType,
348                                      QStringList& theHyps ) const
349 {
350   theHyps.clear();
351   QStringList aHypTypeNameList = SMESH::GetAvailableHypotheses(
352     theHypType == Algo , theDim, theHypType == AddHyp );
353   QStringList::const_iterator anIter;
354   for ( anIter = aHypTypeNameList.begin(); anIter != aHypTypeNameList.end(); ++anIter )
355   {
356     HypothesisData* aData = SMESH::GetHypothesisData( *anIter );
357     theHyps.append( aData->Label );
358   }
359 }
360
361 //================================================================================
362 /*!
363  * \brief Gets existing hypotheses or algorithms
364   * \param theDim - specifies dimension of returned hypotheses/algorifms
365   * \param theHypType - specifies whether algorims or hypotheses or additional ones
366   * are retrieved (possible values are in HypType enumeration)
367   * \param theFather - start object for finding ( may be component, mesh, or sub-mesh )
368   * \param theHyps - output list of names.
369   * \param theHypVars - output list of variables.
370  *
371  * Gets existing (i.e. already created) hypotheses or algorithm in accordance with
372  * input parameters
373  */
374 //================================================================================
375 void SMESHGUI_MeshOp::existingHyps( const int theDim,
376                                     const int theHypType,
377                                     _PTR(SObject) theFather,
378                                     QStringList& theHyps,
379                                     QValueList<SMESH::SMESH_Hypothesis_var>& theHypVars )
380 {
381   // Clear hypoheses list
382   theHyps.clear();
383   theHypVars.clear();
384
385   if ( !theFather )
386     return;
387
388   _PTR(SObject)          aHypRoot;
389   _PTR(GenericAttribute) anAttr;
390   _PTR(AttributeName)    aName;
391   _PTR(AttributeIOR)     anIOR;
392
393   bool isMesh = !_CAST( SComponent, theFather );
394   int aPart = -1;
395   if ( isMesh )
396     aPart = theHypType == Algo ? 3 : 2;
397   else
398     aPart = theHypType == Algo ? 2 : 1;
399
400   if ( theFather->FindSubObject( aPart, aHypRoot ) )
401   {
402     _PTR(ChildIterator) anIter =
403       SMESH::GetActiveStudyDocument()->NewChildIterator( aHypRoot );
404     for (; anIter->More(); anIter->Next() )
405     {
406       _PTR(SObject) anObj = anIter->Value();
407       if ( isMesh ) // i.e. mesh or submesh
408       {
409         _PTR(SObject) aRefObj;
410         if ( anObj->ReferencedObject( aRefObj ) )
411           anObj = aRefObj;
412         else
413           continue;
414       }
415       if ( anObj->FindAttribute( anAttr, "AttributeName" ) )
416       {
417         aName = anAttr;
418         CORBA::Object_var aVar = _CAST(SObject,anObj)->GetObject();
419         if ( !CORBA::is_nil( aVar ) )
420         {
421           SMESH::SMESH_Hypothesis_var aHypVar = SMESH::SMESH_Hypothesis::_narrow( aVar );
422           if ( !aHypVar->_is_nil() )
423           {
424             QString aHypType( aHypVar->GetName() );
425             HypothesisData* aData = SMESH::GetHypothesisData( aHypType );
426             if ( ( theDim == -1 || aData->Dim.contains( theDim ) ) &&
427                  ( theHypType == AddHyp ) == aData->IsAux )
428             {
429               theHyps.append( aName->Value().c_str() );
430               theHypVars.append( aHypVar );
431             }
432           }
433         }
434       }
435     }
436   }
437 }
438
439 //================================================================================
440 /*!
441  * \brief Calls plugin methods for hypothesis creation
442   * \param theHypType - specifies whether main hypotheses or additional ones
443   * are created
444   * \param theIndex - index of type of hypothesis to be cerated
445  *
446  * Speicfies dimension of hypothesis to be created (using sender() method), specifies
447  * its type and calls plugin methods for hypothesis creation
448  */
449 //================================================================================
450 void SMESHGUI_MeshOp::onCreateHyp( const int theHypType, const int theIndex )
451 {
452   // Speicfies dimension of hypothesis to be created
453   const QObject* aSender = sender();
454   int aDim = -1;
455   for ( int i = SMESH::DIM_1D; i <= SMESH::DIM_3D; i++ )
456     if ( aSender == myDlg->tab( i ) )
457       aDim = i;
458   if ( aDim == -1 )
459     return;
460
461   // Speicfies type of hypothesis to be created
462   QStringList aHypTypeNames = SMESH::GetAvailableHypotheses( false , aDim, theHypType == AddHyp );
463   if ( theIndex < 0 || theIndex >= aHypTypeNames.count() )
464     return;
465
466   QString aHypTypeName = aHypTypeNames[ theIndex ];
467   HypothesisData* aData = SMESH::GetHypothesisData( aHypTypeName.latin1() );
468   if ( aData == 0 )
469     return;
470
471   QString aClientLibName = aData->ClientLibName;
472   QStringList anOldHyps;
473   _PTR(SComponent) aFather = SMESH::GetActiveStudyDocument()->FindComponent( "SMESH" );
474   existingHyps( aDim, theHypType, aFather, anOldHyps, myExistingHyps[ aDim ][ theHypType ] );
475
476   if ( aClientLibName == "" )
477   {
478     // Call hypothesis creation server method (without GUI)
479     QString aHypName = aData->Label;
480     SMESH::CreateHypothesis( aHypTypeName, aHypName, false );
481   }
482   else
483   {
484     // Get hypotheses creator client (GUI)
485     SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator( aHypTypeName );
486
487     // Create hypothesis
488     aCreator->CreateHypothesis( false, myDlg );
489   }
490
491   QStringList aNewHyps;
492   aFather = SMESH::GetActiveStudyDocument()->FindComponent( "SMESH" );
493   existingHyps( aDim, theHypType, aFather, aNewHyps, myExistingHyps[ aDim ][ theHypType ] );
494   if ( aNewHyps.count() > anOldHyps.count() )
495   {
496     for ( int i = anOldHyps.count(); i < aNewHyps.count(); i++ )
497       myDlg->tab( aDim )->addHyp( theHypType, aNewHyps[ i ] );
498   }
499 }
500
501 //================================================================================
502 /*!
503  * \brief Calls plugin methods for hypothesis editing
504   * \param theHypType - specifies whether main hypothesis or additional one
505   * is edited
506   * \param theIndex - index of existing hypothesis
507  *
508  * Calls plugin methods for hypothesis editing
509  */
510 //================================================================================
511 void SMESHGUI_MeshOp::onEditHyp( const int theHypType, const int theIndex )
512 {
513   // Speicfies dimension of hypothesis to be created
514   const QObject* aSender = sender();
515   int aDim = -1;
516   for ( int i = SMESH::DIM_1D; i <= SMESH::DIM_3D; i++ )
517     if ( aSender == myDlg->tab( i ) )
518       aDim = i;
519   if ( aDim == -1 )
520     return;
521
522   QValueList<SMESH::SMESH_Hypothesis_var> aList = myExistingHyps[ aDim ][ theHypType ];
523   SMESH::SMESH_Hypothesis_var aHyp = aList[ theIndex - 1 ];
524   if ( aHyp->_is_nil() )
525     return;
526
527   char* aTypeName = aHyp->GetName();
528   SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator( aTypeName );
529   if ( aCreator )
530     aCreator->EditHypothesis( aHyp );
531 }
532
533 //================================================================================
534 /*!
535  * \brief Creates mesh
536   * \param theMess - Output parameter intended for returning error message
537   * \retval bool  - TRUE if mesh is created, FALSE otherwise
538  *
539  * Creates mesh
540  */
541 //================================================================================
542 bool SMESHGUI_MeshOp::createMesh( QString& theMess )
543 {
544   theMess = "";
545
546   QString aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
547   _PTR(SObject) pGeom = studyDS()->FindObjectID( aGeomEntry.latin1() );
548   GEOM::GEOM_Object_var aGeomVar =
549     GEOM::GEOM_Object::_narrow( _CAST( SObject,pGeom )->GetObject() );
550
551   SMESH::SMESH_Gen_var aSMESHGen = SMESHGUI::GetSMESHGen();
552   if ( aSMESHGen->_is_nil() )
553     return false;
554
555   SUIT_OverrideCursor aWaitCursor;
556
557   // create mesh
558   SMESH::SMESH_Mesh_var aMeshVar = aSMESHGen->CreateMesh( aGeomVar );
559   if ( aMeshVar->_is_nil() )
560     return false;
561   _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshVar.in() );
562   if ( aMeshSO )
563     SMESH::SetName( aMeshSO, myDlg->objectText( SMESHGUI_MeshDlg::Obj ).latin1() );
564
565   for ( int aDim = SMESH::DIM_1D; aDim <= SMESH::DIM_3D; aDim++ )
566   {
567     // assign hypotheses
568     for ( int aHypType = MainHyp; aHypType <= AddHyp; aHypType++ )
569     {
570       int aHypIndex = currentHyp( aDim, aHypType );
571       if ( aHypIndex >= 0 && aHypIndex < myExistingHyps[ aDim ][ aHypType ].count() )
572       {
573         SMESH::SMESH_Hypothesis_var aHypVar = myExistingHyps[ aDim ][ aHypType ][ aHypIndex ];
574         if ( !aHypVar->_is_nil() )
575           SMESH::AddHypothesisOnMesh( aMeshVar, aHypVar );
576       }
577     }
578     // find or create algorithm
579     SMESH::SMESH_Hypothesis_var anAlgoVar = getAlgo( aDim );
580     if ( !anAlgoVar->_is_nil() )
581       SMESH::AddHypothesisOnMesh( aMeshVar, anAlgoVar );
582   }
583   return true;
584 }
585
586 //================================================================================
587 /*!
588  * \brief Creates sub-mesh
589   * \param theMess - Output parameter intended for returning error message
590   * \retval bool  - TRUE if sub-mesh is created, FALSE otherwise
591  *
592  * Creates sub-mesh
593  */
594 //================================================================================
595 bool SMESHGUI_MeshOp::createSubMesh( QString& theMess )
596 {
597   theMess = "";
598
599   SMESH::SMESH_Gen_var aSMESHGen = SMESHGUI::GetSMESHGen();
600   if ( aSMESHGen->_is_nil() )
601     return false;
602
603   // get mesh object
604   QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
605   _PTR(SObject) pMesh = studyDS()->FindObjectID( aMeshEntry.latin1() );
606   SMESH::SMESH_Mesh_var aMeshVar =
607     SMESH::SMESH_Mesh::_narrow( _CAST( SObject,pMesh )->GetObject() );
608
609   // get geom object
610   QString aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
611   _PTR(SObject) pGeom = studyDS()->FindObjectID( aGeomEntry.latin1() );
612   GEOM::GEOM_Object_var aGeomVar =
613     GEOM::GEOM_Object::_narrow( _CAST( SObject,pGeom )->GetObject() );
614
615   SUIT_OverrideCursor aWaitCursor;
616
617   // create sub-mesh
618   QString aName = myDlg->objectText( SMESHGUI_MeshDlg::Obj );
619   SMESH::SMESH_subMesh_var aSubMeshVar = aMeshVar->GetSubMesh( aGeomVar, aName.latin1() );
620
621   for ( int aDim = SMESH::DIM_1D; aDim <= SMESH::DIM_3D; aDim++ )
622   {
623     // find or create algorithm
624     SMESH::SMESH_Hypothesis_var anAlgoVar = getAlgo( aDim );
625     if ( !anAlgoVar->_is_nil() )
626       SMESH::AddHypothesisOnSubMesh( aSubMeshVar, anAlgoVar );
627     // assign hypotheses
628     for ( int aHypType = MainHyp; aHypType <= AddHyp; aHypType++ )
629     {
630       int aHypIndex = currentHyp( aDim, aHypType );
631       if ( aHypIndex >= 0 && aHypIndex < myExistingHyps[ aDim ][ aHypType ].count() )
632       {
633         SMESH::SMESH_Hypothesis_var aHypVar =
634           myExistingHyps[ aDim ][ aHypType ][ aHypIndex ];
635         if ( !aHypVar->_is_nil() )
636           SMESH::AddHypothesisOnSubMesh( aSubMeshVar, aHypVar );
637       }
638     }
639   }
640   return true;
641 }
642
643 //================================================================================
644 /*!
645  * \brief Gets current hypothesis or algorithms
646   * \param theDim - dimension of hypothesis or algorithm
647   * \param theHypType - Type of hypothesis (Algo, MainHyp, AddHyp)
648   * \retval int - current hypothesis or algorithms
649  *
650  * Gets current hypothesis or algorithms
651  */
652 //================================================================================
653 int SMESHGUI_MeshOp::currentHyp( const int theDim, const int theHypType ) const
654 {
655   return myDlg->tab( theDim )->currentHyp( theHypType ) - 1;
656 }
657
658 //================================================================================
659 /*!
660  * \brief Sets current hypothesis or algorithms
661   * \param theDim - dimension of hypothesis or algorithm
662   * \param theHypType - Type of hypothesis (Algo, MainHyp, AddHyp)
663   * \param theIndex - Index of hypothesis
664  *
665  * Gets current hypothesis or algorithms
666  */
667 //================================================================================
668 void SMESHGUI_MeshOp::setCurrentHyp( const int theDim,
669                                      const int theHypType,
670                                      const int theIndex )
671 {
672   myDlg->tab( theDim )->setCurrentHyp( theHypType, theIndex + 1 );
673 }
674
675 //================================================================================
676 /*!
677  * \brief Generates default and sets mesh/submesh name
678  *
679  * Generates and sets default mesh/submesh name(Mesh_1, Mesh_2, etc.)
680  */
681 //================================================================================
682 void SMESHGUI_MeshOp::setDefaultName() const
683 {
684   QString aResName;
685
686   _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
687   int i = 1;
688   QString aPrefix = tr( myIsMesh ? "SMESH_OBJECT_MESH" : "SMESH_SUBMESH" ) + "_";
689   _PTR(SObject) anObj;
690   do
691   {
692     aResName = aPrefix + QString::number( i++ );
693     anObj = aStudy->FindObject( aResName.latin1() );
694   }
695   while ( anObj );
696
697   QLineEdit* aControl = ( QLineEdit* )myDlg->objectWg(
698     SMESHGUI_MeshDlg::Obj, SMESHGUI_MeshDlg::Control );
699   aControl->setText( aResName );
700 }
701
702 //================================================================================
703 /*!
704  * \brief Gets algorithm or creates it if necessary
705   * \param theDim - specifies dimension of returned hypotheses/algorifms
706   * \retval SMESH::SMESH_Hypothesis_var - algorithm
707  *
708  * Gets algorithm or creates it if necessary
709  */
710 //================================================================================
711 SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim )
712 {
713   SMESH::SMESH_Hypothesis_var anAlgoVar;
714   int aHypIndex = currentHyp( theDim, Algo );
715   QStringList aHypTypeNameList = SMESH::GetAvailableHypotheses( true, theDim, false );
716   if ( aHypIndex < 0 || aHypIndex >= aHypTypeNameList.count() )
717     return anAlgoVar;
718   QString aHypName = aHypTypeNameList[ aHypIndex ];
719   QValueList<SMESH::SMESH_Hypothesis_var>& aHypVarList = myExistingHyps[ theDim ][ Algo ];
720   QValueList<SMESH::SMESH_Hypothesis_var>::iterator anIter;
721   for ( anIter = aHypVarList.begin(); anIter != aHypVarList.end(); anIter++ )
722   {
723     SMESH::SMESH_Hypothesis_var aHypVar = *anIter;
724     if ( !aHypVar->_is_nil() && aHypName == aHypVar->GetName() )
725     {
726       anAlgoVar = aHypVar;
727       break;
728     }
729   }
730   if ( anAlgoVar->_is_nil() )
731   {
732     HypothesisData* aHypData = SMESH::GetHypothesisData( aHypName );
733     if ( aHypData )
734     {
735       QString aClientLibName = aHypData->ClientLibName;
736       if ( aClientLibName == "" )
737         SMESH::CreateHypothesis( aHypName, aHypData->Label, true );
738       else
739       {
740         SMESHGUI_GenericHypothesisCreator* aCreator =
741           SMESH::GetHypothesisCreator( aHypName );
742         if ( aCreator )
743           aCreator->CreateHypothesis( true, myDlg );
744       }
745       QStringList tmpList;
746       _PTR(SComponent) aFather = SMESH::GetActiveStudyDocument()->FindComponent( "SMESH" );
747       existingHyps( theDim, Algo, aFather, tmpList, myExistingHyps[ theDim ][ Algo ] );
748     }
749
750     QValueList<SMESH::SMESH_Hypothesis_var>& aNewHypVarList = myExistingHyps[ theDim ][ Algo ];
751     for ( anIter = aNewHypVarList.begin(); anIter != aNewHypVarList.end(); ++anIter )
752     {
753       SMESH::SMESH_Hypothesis_var aHypVar = *anIter;
754       if ( !aHypVar->_is_nil() && aHypName == aHypVar->GetName() )
755       {
756         anAlgoVar = aHypVar;
757         break;
758       }
759     }
760   }
761
762   return anAlgoVar._retn();
763 }
764
765 //================================================================================
766 /*!
767  * \brief Reads parameters of edited mesh and assigns them to the dialog
768  *
769  * Reads parameters of edited mesh and assigns them to the dialog (called when
770  * mesh is edited only)
771  */
772 //================================================================================
773 void SMESHGUI_MeshOp::readMesh()
774 {
775   QString anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
776   _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.latin1() );
777   if ( !pObj )
778     return;
779
780   // Get name of mesh if current object is sub-mesh
781   SMESH::SMESH_subMesh_var aSubMeshVar =
782       SMESH::SMESH_subMesh::_narrow( _CAST( SObject,pObj )->GetObject() );
783   if ( !aSubMeshVar->_is_nil() )
784   {
785     SMESH::SMESH_Mesh_var aMeshVar =  aSubMeshVar->GetFather();
786     if ( !aMeshVar->_is_nil() )
787     {
788       _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshVar );
789       QString aMeshName = name( aMeshSO );
790       myDlg->setObjectText( SMESHGUI_MeshDlg::Mesh, aMeshName );
791     }
792   }
793
794   // Get name of geometry object
795   GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj );
796   if ( !aGeomVar->_is_nil() )
797   {
798     _PTR(SObject) aGeomSO = studyDS()->FindObjectID( aGeomVar->GetStudyEntry() );
799     QString aShapeName = name( aGeomSO );
800     myDlg->setObjectText( SMESHGUI_MeshDlg::Geom, aShapeName );
801   }
802
803   // Get hypotheses and algorithms assigned to the mesh/sub-mesh
804   for ( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ )
805   {
806     // get algorithm
807     QStringList anExisting;
808     int aHypIndex = -1;
809     existingHyps( dim, Algo, pObj, anExisting, myObjHyps[ dim ][ Algo ] );
810     if ( myObjHyps[ dim ][ Algo ].count() > 0 )
811     {
812       SMESH::SMESH_Hypothesis_var aVar = myObjHyps[ dim ][ Algo ].first();
813       QString aHypTypeName = aVar->GetName();
814
815       QStringList aHypTypeNameList = SMESH::GetAvailableHypotheses( true , dim, false );
816       for ( int i = 0, n = aHypTypeNameList.count(); i < n; i++ )
817         if ( aHypTypeName == aHypTypeNameList[ i ] )
818         {
819           aHypIndex = i;
820           break;
821         }
822     }
823     setCurrentHyp( dim, Algo, aHypIndex );
824
825     // get hypotheses
826     for ( int hypType = MainHyp; hypType <= AddHyp; hypType++ )
827     {
828       // get hypotheses
829       existingHyps( dim, hypType, pObj, anExisting, myObjHyps[ dim ][ hypType ] );
830       // find index of requered hypothesis among existing ones for this dimension
831       // and hyp types
832       int aHypIndex = -1;
833       if ( myObjHyps[ dim ][ hypType ].count() > 0 )
834         aHypIndex = find( myObjHyps[ dim ][ hypType ].first(),
835                           myExistingHyps[ dim ][ hypType ] );
836       setCurrentHyp( dim, hypType, aHypIndex );
837     }
838   }
839 }
840
841 //================================================================================
842 /*!
843  * \brief Gets name of object
844   * \param theSO - SObject
845   * \retval QString - name of object
846  *
847  * Gets name of object
848  */
849 //================================================================================
850 QString SMESHGUI_MeshOp::name( _PTR(SObject) theSO ) const
851 {
852   QString aResName;
853   if ( theSO )
854   {
855     _PTR(GenericAttribute) anAttr;
856     _PTR(AttributeName)    aNameAttr;
857     if ( theSO->FindAttribute( anAttr, "AttributeName" ) )
858     {
859       aNameAttr = anAttr;
860       aResName = aNameAttr->Value().c_str();
861     }
862   }
863   return aResName;
864 }
865
866 //================================================================================
867 /*!
868  * \brief Finds hypothesis in input list
869   * \param theHyp - hypothesis to be found
870   * \param theHypList - input list of hypotheses
871   * \retval int - index of hypothesis or -1 if it is not found
872  *
873  * Finds position of hypothesis in input list
874  */
875 //================================================================================
876 int SMESHGUI_MeshOp::find( const SMESH::SMESH_Hypothesis_var& theHyp,
877                            const QValueList<SMESH::SMESH_Hypothesis_var>& theHypList ) const
878 {
879   int aRes = -1;
880   if ( !theHyp->_is_nil() )
881   {
882     int i = 0;
883     QValueList<SMESH::SMESH_Hypothesis_var>::const_iterator anIter;
884     for ( anIter = theHypList.begin(); anIter != theHypList.end(); ++ anIter )
885     {
886       if ( theHyp->_is_equivalent( *anIter ) )
887       {
888         aRes = i;
889         break;
890       }
891       i++;
892     }
893   }
894   return aRes;
895 }
896
897 //================================================================================
898 /*!
899  * \brief Edits mesh or sub-mesh
900   * \param theMess - Output parameter intended for returning error message
901   * \retval bool  - TRUE if mesh is edited succesfully, FALSE otherwise
902  *
903  * Assigns new name hypotheses and algoriths to the mesh or sub-mesh
904  */
905 //================================================================================
906 bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess )
907 {
908   theMess = "";
909
910   SMESH::SMESH_Gen_var aSMESHGen = SMESHGUI::GetSMESHGen();
911   if ( aSMESHGen->_is_nil() )
912     return false;
913
914   QString anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
915   _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.latin1() );
916   if ( !pObj )
917     return false;
918
919   SUIT_OverrideCursor aWaitCursor;
920
921   // Set new name
922   SMESH::SetName( pObj, myDlg->objectText( SMESHGUI_MeshDlg::Obj ).latin1() );
923
924   // Assign new hypotheses and algorithms
925   for ( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ )
926   {
927     // find or create algorithm
928     bool toDelete = false, toAdd = true;
929     SMESH::SMESH_Hypothesis_var anAlgoVar = getAlgo( dim );
930     if ( anAlgoVar->_is_nil() ) {
931       toAdd = false;
932     }
933     if ( myObjHyps[ dim ][ Algo ].count() > 0 ) {
934       SMESH::SMESH_Hypothesis_var anOldAlgo = myObjHyps[ dim ][ Algo ].first();
935       if ( toAdd ) {
936         if ( strcmp(anOldAlgo->GetName(), anAlgoVar->GetName()) == 0 ) {
937           toAdd = false;
938         } else {
939           toDelete = true;
940         }
941       } else {
942         toDelete = true;
943       }
944     }
945     // remove old algorithm
946     if ( toDelete )
947       SMESH::RemoveHypothesisOrAlgorithmOnMesh
948         ( pObj, myObjHyps[ dim ][ Algo ].first() );
949
950     // assign new algorithm
951     if ( toAdd ) {
952       SMESH::SMESH_Mesh_var aMeshVar =
953         SMESH::SMESH_Mesh::_narrow( _CAST(SObject,pObj)->GetObject() );
954       bool isMesh = !aMeshVar->_is_nil();
955       if ( isMesh ) {
956         SMESH::AddHypothesisOnMesh( aMeshVar, anAlgoVar );
957       } else {
958         SMESH::SMESH_subMesh_var aVar =
959           SMESH::SMESH_subMesh::_narrow( _CAST(SObject,pObj)->GetObject() );
960         if ( !aVar->_is_nil() )
961           SMESH::AddHypothesisOnSubMesh( aVar, anAlgoVar );
962       }
963     }
964
965     // assign hypotheses
966     for ( int hypType = MainHyp; hypType <= AddHyp; hypType++ )
967     {
968       int aNewHypIndex = currentHyp( dim, hypType );
969       int anOldHypIndex = -1;
970       if ( myObjHyps[ dim ][ hypType ].count() > 0 )
971         anOldHypIndex = find( myObjHyps[ dim ][ hypType ].first(),
972                               myExistingHyps[ dim ][ hypType ] );
973       if ( aNewHypIndex != anOldHypIndex )
974       {
975         // remove old hypotheses
976         if ( anOldHypIndex >= 0 )
977           SMESH::RemoveHypothesisOrAlgorithmOnMesh(
978             pObj, myExistingHyps[ dim ][ hypType ][ anOldHypIndex ] );
979
980         // assign new hypotheses
981         if ( aNewHypIndex != -1 )
982         {
983           SMESH::SMESH_Mesh_var aMeshVar =
984               SMESH::SMESH_Mesh::_narrow( _CAST(SObject,pObj)->GetObject() );
985           bool isMesh = !aMeshVar->_is_nil();
986           if ( isMesh )
987           {
988             SMESH::AddHypothesisOnMesh(
989               aMeshVar, myExistingHyps[ dim ][ hypType ][ aNewHypIndex ] );
990           }
991           else
992           {
993             SMESH::SMESH_subMesh_var aVar =
994               SMESH::SMESH_subMesh::_narrow( _CAST(SObject,pObj)->GetObject() );
995             if ( !aVar->_is_nil() )
996               SMESH::AddHypothesisOnSubMesh(
997                 aVar, myExistingHyps[ dim ][ hypType ][ aNewHypIndex ] );
998           }
999         }
1000         // reread all hypotheses of mesh if necessary
1001         QStringList anExisting;
1002         existingHyps( dim, hypType, pObj, anExisting, myObjHyps[ dim ][ hypType ] );
1003       }
1004     }
1005   }
1006
1007   return true;
1008 }
1009
1010 //================================================================================
1011 /*!
1012  * \brief Verifies whether given operator is valid for this one
1013   * \param theOtherOp - other operation
1014   * \return Returns TRUE if the given operator is valid for this one, FALSE otherwise
1015 *
1016 * Virtual method redefined from base class verifies whether given operator is valid for
1017 * this one (i.e. can be started "above" this operator). In current implementation method
1018 * retuns false if theOtherOp operation is not intended for deleting objects or mesh
1019 * elements.
1020 */
1021 //================================================================================
1022 bool SMESHGUI_MeshOp::isValid( SUIT_Operation* theOp ) const
1023 {
1024   return SMESHGUI_Operation::isValid( theOp ) && !theOp->inherits( "SMESHGUI_MeshOp" );
1025 }