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