Salome HOME
581aa53265474bc1eb8ae2a55150c67a504da002
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_GroupOnShapeDlg.cxx
1 //  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  This library is free software; you can redistribute it and/or
4 //  modify it under the terms of the GNU Lesser General Public
5 //  License as published by the Free Software Foundation; either
6 //  version 2.1 of the License.
7 //
8 //  This library is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 //  Lesser General Public License for more details.
12 //
13 //  You should have received a copy of the GNU Lesser General Public
14 //  License along with this library; if not, write to the Free Software
15 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 //  SMESH SMESHGUI : GUI for SMESH component
21 // File      : SMESHGUI_GroupOnShapeDlg.cxx
22 // Created   : Wed Sep 17 18:36:51 2008
23 // Author    : Edward AGAPOV (eap)
24 // Module    : SMESH
25 // IDL Headers
26 //
27 #include "SMESHGUI_GroupOnShapeDlg.h"
28
29 #include "SMESH_TypeFilter.hxx"
30 #include "SMESHGUI.h"
31 #include "SMESHGUI_Utils.h"
32 #include "SMESHGUI_GEOMGenUtils.h"
33
34 #include <GeometryGUI.h>
35 #include <GEOM_SelectionFilter.h>
36
37 #include <SUIT_Session.h>
38 #include <SUIT_OverrideCursor.h>
39 #include <LightApp_UpdateFlags.h>
40 #include <SUIT_ResourceMgr.h>
41
42 #include <SALOMEconfig.h>
43 #include CORBA_SERVER_HEADER(SMESH_Mesh)
44 #include CORBA_SERVER_HEADER(SMESH_Group)
45
46 #include <QGroupBox>
47 #include <QLayout>
48 #include <QFrame>
49 #include <QLabel>
50 #include <QPushButton>
51 #include <QListWidget>
52 #include <QLineEdit>
53
54 #define SPACING 6
55 #define MARGIN  11
56
57 enum { _MESH, _ELEM_GEOM, _NODE_GEOM };
58
59 SMESHGUI_GroupOnShapeDlg::SMESHGUI_GroupOnShapeDlg()
60   : SMESHGUI_Dialog( 0, false, true )
61 {
62   QPixmap image (resourceMgr()->loadPixmap("SMESH", tr("ICON_SELECT")));
63
64   // Name
65   //QLabel* nameLabel = new QLabel( tr( "SMESH_NAME" ), mainFrame() );
66   //myGrpNameLine = new QLineEdit( mainFrame() );
67
68   // Mesh
69   QLabel* meshLabel = new QLabel( tr( "SMESH_OBJECT_MESH" ), mainFrame() );
70   myMeshBtn = new QPushButton( mainFrame() );
71   myMeshBtn->setCheckable(true);
72   myMeshBtn->setIcon(image);
73   myMeshLine = new QLineEdit( mainFrame() );
74   myMeshLine->setReadOnly(true);
75
76   // Elem geom
77
78   QGroupBox* elemsGrp = new QGroupBox( tr( "SMESH_ELEMENTS" ), mainFrame() );
79   QLabel* label = new QLabel( tr( "SMESH_GEOM" ), elemsGrp );
80   myElemGeomBtn = new QPushButton( elemsGrp );
81   myElemGeomBtn->setCheckable(true);
82   myElemGeomBtn->setIcon(image);
83   myElemGeomList = new QListWidget( elemsGrp );
84   myElemGeomList->setSelectionMode(QListWidget::NoSelection);
85
86   QGridLayout* elemLay = new QGridLayout(elemsGrp);
87   elemLay->setSpacing( SPACING );
88   elemLay->setMargin( MARGIN );
89   elemLay->setRowStretch( 1, 1 );
90   elemLay->addWidget( label, 0, 0 );
91   elemLay->addWidget( myElemGeomBtn, 0, 1 );
92   elemLay->addWidget( myElemGeomList, 0, 2, 2, 1);
93
94   // Node geom
95
96   QGroupBox* nodesGrp = new QGroupBox( tr( "SMESH_NODES" ), mainFrame() );
97
98   label = new QLabel( tr( "SMESH_GEOM" ), nodesGrp );
99   myNodeGeomBtn = new QPushButton( nodesGrp );
100   myNodeGeomBtn->setCheckable(true);
101   myNodeGeomBtn->setIcon(image);
102   myNodeGeomList = new QListWidget( nodesGrp );
103   myNodeGeomList->setSelectionMode(QListWidget::NoSelection);
104
105   QGridLayout* nodeLay = new QGridLayout(nodesGrp);
106   nodeLay->setSpacing( SPACING );
107   nodeLay->setMargin( MARGIN );
108   nodeLay->setRowStretch( 1, 1 );
109   nodeLay->addWidget( label, 0, 0 );
110   nodeLay->addWidget( myNodeGeomBtn, 0, 1 );
111   nodeLay->addWidget(myNodeGeomList, 0, 2, 2, 1);
112
113   // Fill layout
114   QGridLayout* aLay = new QGridLayout( mainFrame());
115   aLay->setSpacing( SPACING );
116   aLay->setMargin( MARGIN );
117   //aLay->addWidget( nameLabel, 0, 0 );
118   //aLay->addWidget( myGrpNameLine, 0, 2 );
119   aLay->addWidget( meshLabel, 1, 0 );
120   aLay->addWidget( myMeshBtn, 1, 1 );
121   aLay->addWidget( myMeshLine,1, 2 );
122   aLay->addWidget( elemsGrp, 2, 1, 1, 3 );
123   aLay->addWidget( nodesGrp, 3, 1, 1, 3 );
124
125   setWindowTitle( tr( "SMESH_CREATE_GROUP_FROM_GEOM" ) );
126 }
127
128 SMESHGUI_GroupOnShapeDlg::~SMESHGUI_GroupOnShapeDlg()
129 {
130 }
131
132 //================================================================================
133 /*!
134  * \brief slot to enable/diable [Apply]
135  */
136 //================================================================================
137
138 void SMESHGUI_GroupOnShapeDlg::updateButtons()
139 {
140   bool enable =
141     /*!myGrpNameLine->text().isEmpty() &&*/ myElemGeomList->count() + myNodeGeomList->count();
142
143   button(Apply)->setEnabled( enable );
144   button(OK)->setEnabled( enable );
145 }
146
147 //================================================================================
148 /*!
149  * \brief initialization
150  */
151 //================================================================================
152
153 void SMESHGUI_GroupOnShapeDlg::init()
154 {
155   //myGrpNameLine->setText("");
156
157   myMeshBtn->setChecked( true );
158   myMeshLine->setText("");
159
160   myElemGeomBtn->setChecked(false);
161   myElemGeomBtn->setEnabled(false);
162   myElemGeomList->clear();
163   myNodeGeomBtn->setChecked(false);
164   myNodeGeomBtn->setEnabled(false);
165   myNodeGeomList->clear();
166
167   updateButtons();
168 }
169
170 //================================================================================
171 /*!
172  * \brief operation constructor
173  */
174 //================================================================================
175
176 SMESHGUI_GroupOnShapeOp::SMESHGUI_GroupOnShapeOp()
177   : SMESHGUI_SelectionOp(ActorSelection),
178     myDlg( 0 )
179 {
180   myHelpFileName = "create_groups_from_geometry_page.html";
181 }
182
183 SMESHGUI_GroupOnShapeOp::~SMESHGUI_GroupOnShapeOp()
184 {
185   if ( myDlg )
186     delete myDlg;
187 }
188 //================================================================================
189 /*!
190  * \brief Gets dialog of this operation
191   * \retval LightApp_Dialog* - pointer to dialog of this operation
192 */
193 //================================================================================
194
195 LightApp_Dialog* SMESHGUI_GroupOnShapeOp::dlg() const
196 {
197   return myDlg;
198 }
199
200 //================================================================================
201 /*!
202  * \brief return type of mesh group by geom object
203  */
204 //================================================================================
205
206 static SMESH::ElementType elementType(GEOM::GEOM_Object_var& geom)
207 {
208   if ( !geom->_is_nil() ) {
209     switch ( geom->GetShapeType() ) {
210     case GEOM::VERTEX:   return SMESH::NODE;
211     case GEOM::EDGE:     return SMESH::EDGE;
212     case GEOM::WIRE:     return SMESH::EDGE;
213     case GEOM::FACE:     return SMESH::FACE;
214     case GEOM::SHELL:    return SMESH::FACE;
215     case GEOM::SOLID:    return SMESH::VOLUME;
216     case GEOM::COMPSOLID:return SMESH::VOLUME;
217     case GEOM::COMPOUND: break;
218     default:             return SMESH::ALL;
219     }
220     _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
221     GEOM::GEOM_IShapesOperations_var aShapeOp =
222       SMESH::GetGEOMGen()->GetIShapesOperations(aStudy->StudyId());
223
224     if ( geom->GetType() == 37 ) { // geom group
225       GEOM::GEOM_IGroupOperations_var  aGroupOp =
226         SMESH::GetGEOMGen()->GetIGroupOperations(aStudy->StudyId());
227       if ( !aGroupOp->_is_nil() ) {
228         GEOM::GEOM_Object_var mainShape = aGroupOp->GetMainShape( geom );
229         GEOM::ListOfLong_var        ids = aGroupOp->GetObjects( geom );
230         if ( ids->length() && !mainShape->_is_nil() && !aShapeOp->_is_nil() ) {
231           GEOM::GEOM_Object_var member = aShapeOp->GetSubShape( mainShape, ids[0] );
232           return elementType( member );
233         }
234       }
235     }
236     else if ( !aShapeOp->_is_nil() ) { // just a compoud shape
237       GEOM::ListOfLong_var ids = aShapeOp->SubShapeAllIDs( geom, GEOM::SHAPE, false );
238       if ( ids->length() ) {
239         GEOM::GEOM_Object_var member = aShapeOp->GetSubShape( geom, ids[0] );
240         return elementType( member );
241       }
242     }
243   }
244   return SMESH::ALL;
245 }
246
247 //================================================================================
248 /*!
249  * \brief initialization
250  */
251 //================================================================================
252
253 void SMESHGUI_GroupOnShapeOp::init()
254 {
255   myMeshID="";
256   myElemGeoIDs.clear();
257   myNodeGeoIDs.clear();
258
259   myDlg->init();
260   removeCustomFilters();
261   onActivateObject( _MESH ); // install filter
262 }
263
264 //================================================================================
265 /*!
266  * \brief start operation
267  */
268 //================================================================================
269
270 void SMESHGUI_GroupOnShapeOp::startOperation()
271 {
272   if (!myDlg)
273   {
274     myDlg = new SMESHGUI_GroupOnShapeDlg();
275     connect(myDlg->myMeshBtn,     SIGNAL(clicked()), this, SLOT(onButtonClick()));
276     connect(myDlg->myElemGeomBtn, SIGNAL(clicked()), this, SLOT(onButtonClick()));
277     connect(myDlg->myNodeGeomBtn, SIGNAL(clicked()), this, SLOT(onButtonClick()));
278     //connect(myDlg->myGrpNameLine, SIGNAL(textChanged(const QString&)),myDlg,SLOT(updateButtons()));
279   }
280   SMESHGUI_SelectionOp::startOperation();
281
282   init();
283   myDlg->show();
284 }
285
286 //================================================================================
287 /*!
288  * \brief create groups
289  */
290 //================================================================================
291
292 bool SMESHGUI_GroupOnShapeOp::onApply()
293 {
294   SUIT_OverrideCursor aWaitCursor;
295
296   if (isStudyLocked())
297     return false;
298
299   // study
300   _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
301   if ( !aStudy ) return false;
302
303   // mesh
304   _PTR(SObject) meshSO = aStudy->FindObjectID( myMeshID.toLatin1().data() );
305   SMESH::SMESH_Mesh_var mesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( meshSO );
306   if ( mesh->_is_nil() ) return false;
307
308   // names of all existing groups
309 //   QStringList groupNames;
310 //   QString givenName = myDlg->myGrpNameLine->text();
311 //   if ( !givenName.isEmpty() ) {
312 //     SMESH::ListOfGroups_var groups = mesh->GetGroups();
313 //     for ( int i = 0; i < groups->length(); ++i ) {
314 //       CORBA::String_var name = groups[i]->GetName();
315 //       groupNames.append( name.in() );
316 //     }
317 //   }
318
319   // create groups
320   SMESH::SMESH_GroupOnGeom_var group;
321   for ( int isNode = 0; isNode < 2; ++isNode ) // elems and then nodes
322   {
323     QStringList::iterator geomID = isNode ? myNodeGeoIDs.begin() : myElemGeoIDs.begin();
324     QStringList::iterator geomEnd = isNode ? myNodeGeoIDs.end() : myElemGeoIDs.end();
325
326     for ( int i = 0; geomID != geomEnd; ++geomID, ++i )
327     {
328       // selected geom
329       _PTR(SObject) geomSO = aStudy->FindObjectID( geomID->toLatin1().data() );
330       GEOM::GEOM_Object_var geom = SMESH::SObjectToInterface<GEOM::GEOM_Object>(geomSO);
331       if ( geom->_is_nil() ) continue;
332
333       // group type
334       SMESH::ElementType elemType = isNode ? SMESH::NODE : elementType( geom );
335       if ( elemType == SMESH::ALL )
336         continue;
337
338       // make a unique name
339       QString name =
340         isNode ? myDlg->myNodeGeomList->item(i)->text() : myDlg->myElemGeomList->item(i)->text();
341 //       int nb = 1;
342 //       QString name = myDlg->myGrpNameLine->text() + "_" + QString::number(nb);
343 //       while ( groupNames.contains( name ))
344 //         name = myDlg->myGrpNameLine->text() + "_" + QString::number(++nb);
345 //       groupNames.append( name );
346
347       //printf( "apply() %s %s\n", (*geomID).latin1(), name.latin1() );
348       group = mesh->CreateGroupFromGEOM( elemType, name.toLatin1().data(), geom );
349     }
350   }
351   SMESHGUI::Modified();
352
353   update( UF_ObjBrowser | UF_Model );
354
355   // Re-init controls to create the next group
356   myElemGeoIDs.clear();
357   myNodeGeoIDs.clear();
358   removeCustomFilters();
359   myDlg->myNodeGeomList->clear();
360   myDlg->myElemGeomList->clear();
361   myDlg->myElemGeomBtn->setChecked(false); 
362   myDlg->myNodeGeomBtn->setChecked(false);
363   myDlg->updateButtons();
364
365   return !group->_is_nil();
366 }
367
368 //================================================================================
369 /*!
370  * \brief slot connected to selection buttons
371  */
372 //================================================================================
373
374 void SMESHGUI_GroupOnShapeOp::onButtonClick()
375 {
376   removeCustomFilters();
377
378   if ( sender() == myDlg->myMeshBtn && myDlg->myMeshBtn->isChecked() )
379   {
380     myDlg->myElemGeomBtn->setChecked(false);
381     myDlg->myNodeGeomBtn->setChecked(false);
382     onActivateObject( _MESH ); // install filter
383   }
384   else if ( sender() == myDlg->myElemGeomBtn && myDlg->myElemGeomBtn->isChecked() )
385   {
386     myDlg->myMeshBtn->setChecked(false);
387     myDlg->myNodeGeomBtn->setChecked(false);
388     onActivateObject( _ELEM_GEOM ); // install filter
389   }
390   else if ( sender() == myDlg->myNodeGeomBtn && myDlg->myNodeGeomBtn->isChecked() )
391   {
392     myDlg->myMeshBtn->setChecked(false);
393     myDlg->myElemGeomBtn->setChecked(false);
394     onActivateObject( _NODE_GEOM ); // install filter
395   }
396   //selectionDone();
397 }
398
399 //================================================================================
400 /*!
401  * \brief Creates selection filter
402   * \param theId - identifier of current selection widget
403   * \retval SUIT_SelectionFilter* - pointer to the created filter or null
404  *
405  * Creates selection filter in accordance with identifier of current selection widget
406  */
407 //================================================================================
408 SUIT_SelectionFilter* SMESHGUI_GroupOnShapeOp::createFilter( const int theId ) const
409 {
410   if ( theId == _ELEM_GEOM || theId == _NODE_GEOM )
411     return new GEOM_SelectionFilter( (SalomeApp_Study*)study(), true );
412   else if ( theId == _MESH )
413     return new SMESH_TypeFilter( MESH );
414   else
415     return ( SUIT_SelectionFilter*) 0;
416 }
417 //================================================================================
418 /*!
419  * \brief Updates dialog's look and feel
420  *
421  * Virtual method redefined from the base class updates dialog's look and feel
422  */
423 //================================================================================
424 void SMESHGUI_GroupOnShapeOp::selectionDone()
425 {
426   QStringList names, ids;
427   LightApp_Dialog::TypesList types;
428   selected( names, types, ids );
429   int nbSelected = names.size();
430
431   if ( myDlg->myMeshBtn->isChecked() ) // mesh selected
432   {
433     myDlg->myMeshLine->setText("");
434     myMeshID = "";
435     if ( nbSelected == 1 ) {
436       myDlg->myMeshLine->setText( names.front() );
437       myMeshID = ids.front();
438     }
439     myDlg->myElemGeomList->clear();
440     myDlg->myElemGeomBtn->setEnabled( nbSelected == 1 );
441     myDlg->myNodeGeomList->clear();
442     myDlg->myNodeGeomBtn->setEnabled( nbSelected == 1 );
443     myDlg->myElemGeomBtn->click();
444     return;
445   }
446
447   // Filter off inappropriate shapes
448
449   QStringList goodNames, goodIds;
450   if (nbSelected > 0) {
451     // study
452     if (_PTR(Study) aStudy = SMESH::GetActiveStudyDocument()) {
453       // mesh
454       if (_PTR(SObject)  meshSO = aStudy->FindObjectID( myMeshID.toLatin1().data() )) {
455         // shape to mesh
456         _PTR(SObject) anObj, shapeToMesh;
457         if (meshSO->FindSubObject(1, anObj) && anObj->ReferencedObject(shapeToMesh)) {
458           // loop on selected
459           QStringList::iterator name = names.begin(), id = ids.begin(), idEnd = ids.end();
460           for (; id != idEnd; ++id, ++name ) {
461             // shape SO
462             if (_PTR(SObject) shapeSO = aStudy->FindObjectID( id->toLatin1().data() )) {
463             // check if shape SO is a child of shape to mesh 
464               while ( shapeSO && shapeSO->GetID() != shapeToMesh->GetID() )
465                 if  ( shapeSO->Depth() < 2 )
466                   shapeSO.reset();
467                 else
468                   shapeSO = shapeSO->GetFather();
469               if ( shapeSO ) {
470                 //printf( "selectionDone() %s %s\n", (*id).latin1(), (*name).latin1() );
471                 if ( !goodIds.contains( *id )) {
472                   goodIds.append( *id );
473                   goodNames.append( *name );
474                 }
475               }
476             }
477           }
478         }
479       }
480     }
481   }
482
483   if ( myDlg->myElemGeomBtn->isChecked() ) // elem geomerty selection
484   {
485     myDlg->myElemGeomList->clear();
486     myDlg->myElemGeomList->addItems( goodNames );
487     myElemGeoIDs = goodIds;
488   }
489   else if ( myDlg->myNodeGeomBtn->isChecked() ) // Node geomerty selection
490   {
491     myDlg->myNodeGeomList->clear();
492     myDlg->myNodeGeomList->addItems( goodNames );
493     myNodeGeoIDs = goodIds;
494   }
495
496   // enable/diable Apply, which can change at selection
497   myDlg->updateButtons();
498 }