Salome HOME
Fix for problem: Preferences-Mesh-General tab: Display modes ?Nodes? and ?Shrink...
[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 );
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 );
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 );
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 );
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 );
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 );
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     // assign hypotheses
624     for ( int aHypType = MainHyp; aHypType <= AddHyp; aHypType++ )
625     {
626       int aHypIndex = currentHyp( aDim, aHypType );
627       if ( aHypIndex >= 0 && aHypIndex < myExistingHyps[ aDim ][ aHypType ].count() )
628       {
629         SMESH::SMESH_Hypothesis_var aHypVar = 
630           myExistingHyps[ aDim ][ aHypType ][ aHypIndex ];
631         if ( !aHypVar->_is_nil() )
632           SMESH::AddHypothesisOnSubMesh( aSubMeshVar, aHypVar );
633       }
634     }
635     // find or create algorithm
636     SMESH::SMESH_Hypothesis_var anAlgoVar = getAlgo( aDim );
637     if ( !anAlgoVar->_is_nil() )
638       SMESH::AddHypothesisOnSubMesh( aSubMeshVar, anAlgoVar );
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 );
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 );
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     // create algorithm if necessary
928     getAlgo( dim );
929     
930     // assign hypotheses
931     for ( int hypType = Algo; hypType <= AddHyp; hypType++ )
932     {
933       int aNewHypIndex = currentHyp( dim, hypType );
934       int anOldHypIndex = -1;
935       if ( myObjHyps[ dim ][ hypType ].count() > 0 )
936         anOldHypIndex = find( myObjHyps[ dim ][ hypType ].first(), 
937                               myExistingHyps[ dim ][ hypType ] );
938       if ( aNewHypIndex !=  anOldHypIndex )
939       {
940         // remove old hypotheses
941         if ( anOldHypIndex >= 0 )
942           SMESH::RemoveHypothesisOrAlgorithmOnMesh( 
943             pObj, myExistingHyps[ dim ][ hypType ][ anOldHypIndex ] );
944         
945         // assign new hypotheses
946         if ( aNewHypIndex != -1 )
947         {
948           SMESH::SMESH_Mesh_var aMeshVar = 
949               SMESH::SMESH_Mesh::_narrow( _CAST(SObject,pObj)->GetObject() );
950           bool isMesh = !aMeshVar->_is_nil();
951           if ( isMesh )
952           {
953             SMESH::AddHypothesisOnMesh( 
954               aMeshVar, myExistingHyps[ dim ][ hypType ][ aNewHypIndex ] );
955           }
956           else
957           {
958             SMESH::SMESH_subMesh_var aVar = 
959               SMESH::SMESH_subMesh::_narrow( _CAST(SObject,pObj)->GetObject() );
960             if ( !aVar->_is_nil() )
961               SMESH::AddHypothesisOnSubMesh( 
962                 aVar, myExistingHyps[ dim ][ hypType ][ aNewHypIndex ] );
963           }
964         }
965         // reread all hypotheses of mesh if necessary
966         QStringList anExisting;
967         existingHyps( dim, hypType, pObj, anExisting, myObjHyps[ dim ][ hypType ] );
968       }
969     }
970   }
971   
972   return true;
973 }
974
975 //================================================================================
976 /*!
977  * \brief Verifies whether given operator is valid for this one
978   * \param theOtherOp - other operation
979   * \return Returns TRUE if the given operator is valid for this one, FALSE otherwise
980 *
981 * Virtual method redefined from base class verifies whether given operator is valid for
982 * this one (i.e. can be started "above" this operator). In current implementation method
983 * retuns false if theOtherOp operation is not intended for deleting objects or mesh
984 * elements.
985 */
986 //================================================================================
987 bool SMESHGUI_MeshOp::isValid( SUIT_Operation* theOp ) const
988 {
989   return SMESHGUI_Operation::isValid( theOp ) && !theOp->inherits( "SMESHGUI_MeshOp" );
990 }
991
992
993
994
995
996
997
998
999