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