1 // Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
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)
27 #include "SMESHGUI_GroupOnShapeDlg.h"
29 #include "SMESH_TypeFilter.hxx"
31 #include "SMESHGUI_Utils.h"
32 #include "SMESHGUI_GEOMGenUtils.h"
34 #include <GeometryGUI.h>
35 #include <GEOM_SelectionFilter.h>
36 #include <GEOM_wrap.hxx>
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>
44 #include <SALOMEconfig.h>
45 #include CORBA_SERVER_HEADER(SMESH_Mesh)
46 #include CORBA_SERVER_HEADER(SMESH_Group)
52 #include <QPushButton>
53 #include <QListWidget>
59 enum { _MESH, _ELEM_GEOM, _NODE_GEOM };
61 SMESHGUI_GroupOnShapeDlg::SMESHGUI_GroupOnShapeDlg()
62 : SMESHGUI_Dialog( 0, false, true )
64 QPixmap image (resourceMgr()->loadPixmap("SMESH", tr("ICON_SELECT")));
67 //QLabel* nameLabel = new QLabel( tr( "SMESH_NAME" ), mainFrame() );
68 //myGrpNameLine = new QLineEdit( mainFrame() );
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);
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);
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);
99 QGroupBox* nodesGrp = new QGroupBox( tr( "SMESH_NODES" ), mainFrame() );
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);
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);
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 );
128 setWindowTitle( tr( "SMESH_CREATE_GROUP_FROM_GEOM" ) );
131 SMESHGUI_GroupOnShapeDlg::~SMESHGUI_GroupOnShapeDlg()
135 //================================================================================
137 * \brief slot to enable/disable [Apply]
139 //================================================================================
141 void SMESHGUI_GroupOnShapeDlg::updateButtons()
144 /*!myGrpNameLine->text().isEmpty() &&*/ myElemGeomList->count() + myNodeGeomList->count();
146 button(Apply)->setEnabled( enable );
147 button(OK)->setEnabled( enable );
150 //================================================================================
152 * \brief initialization
154 //================================================================================
156 void SMESHGUI_GroupOnShapeDlg::init()
158 //myGrpNameLine->setText("");
160 myMeshBtn->setChecked( true );
161 myMeshLine->setText("");
163 myElemGeomBtn->setChecked(false);
164 myElemGeomBtn->setEnabled(false);
165 myElemGeomList->clear();
166 myNodeGeomBtn->setChecked(false);
167 myNodeGeomBtn->setEnabled(false);
168 myNodeGeomList->clear();
173 //================================================================================
175 * \brief operation constructor
177 //================================================================================
179 SMESHGUI_GroupOnShapeOp::SMESHGUI_GroupOnShapeOp()
180 : SMESHGUI_SelectionOp(ActorSelection),
183 myHelpFileName = "create_groups_from_geometry.html";
186 SMESHGUI_GroupOnShapeOp::~SMESHGUI_GroupOnShapeOp()
191 //================================================================================
193 * \brief Gets dialog of this operation
194 * \retval LightApp_Dialog* - pointer to dialog of this operation
196 //================================================================================
198 LightApp_Dialog* SMESHGUI_GroupOnShapeOp::dlg() const
203 //================================================================================
205 * \brief return type of mesh group by geom object
207 //================================================================================
209 SMESH::ElementType SMESHGUI_GroupOnShapeOp::ElementType(GEOM::GEOM_Object_var geom)
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;
223 GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen( geom );
224 GEOM::GEOM_IShapesOperations_wrap aShapeOp = geomGen->GetIShapesOperations();
226 if ( geom->GetType() == 37 ) // geom group
228 GEOM::GEOM_IGroupOperations_wrap 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 );
239 else if ( !aShapeOp->_is_nil() ) // just a compoud shape
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 );
251 //================================================================================
253 * \brief initialization
255 //================================================================================
257 void SMESHGUI_GroupOnShapeOp::init()
260 myElemGeoIDs.clear();
261 myNodeGeoIDs.clear();
264 removeCustomFilters();
265 onActivateObject( _MESH ); // install filter
268 //================================================================================
270 * \brief start operation
272 //================================================================================
274 void SMESHGUI_GroupOnShapeOp::startOperation()
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()));
284 SMESHGUI_SelectionOp::startOperation();
290 //================================================================================
292 * \brief create groups
294 //================================================================================
296 bool SMESHGUI_GroupOnShapeOp::onApply()
298 SUIT_OverrideCursor aWaitCursor;
300 if (SMESHGUI::isStudyLocked())
304 _PTR(Study) aStudy = SMESH::getStudy();
305 if ( !aStudy ) return false;
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;
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() );
324 SMESH::SMESH_GroupOnGeom_var group;
325 QStringList anEntryList;
326 for ( int isNode = 0; isNode < 2; ++isNode ) // elems and then nodes
328 QStringList::iterator geomID = isNode ? myNodeGeoIDs.begin() : myElemGeoIDs.begin();
329 QStringList::iterator geomEnd = isNode ? myNodeGeoIDs.end() : myElemGeoIDs.end();
331 for ( int i = 0; geomID != geomEnd; ++geomID, ++i )
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;
339 SMESH::ElementType elemType = isNode ? SMESH::NODE : ElementType( geom );
340 if ( elemType == SMESH::ALL )
343 // make a unique name
345 isNode ? myDlg->myNodeGeomList->item(i)->text() : myDlg->myElemGeomList->item(i)->text();
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 );
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() );
359 SMESHGUI::Modified();
361 update( UF_ObjBrowser | UF_Model );
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();
373 if( LightApp_Application* anApp =
374 dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
375 anApp->browseObjects( anEntryList, isApplyAndClose() );
377 return !group->_is_nil();
380 //================================================================================
382 * \brief slot connected to selection buttons
384 //================================================================================
386 void SMESHGUI_GroupOnShapeOp::onButtonClick()
388 removeCustomFilters();
390 if ( sender() == myDlg->myMeshBtn && myDlg->myMeshBtn->isChecked() )
392 myDlg->myElemGeomBtn->setChecked(false);
393 myDlg->myNodeGeomBtn->setChecked(false);
394 onActivateObject( _MESH ); // install filter
396 else if ( sender() == myDlg->myElemGeomBtn && myDlg->myElemGeomBtn->isChecked() )
398 myDlg->myMeshBtn->setChecked(false);
399 myDlg->myNodeGeomBtn->setChecked(false);
400 onActivateObject( _ELEM_GEOM ); // install filter
402 else if ( sender() == myDlg->myNodeGeomBtn && myDlg->myNodeGeomBtn->isChecked() )
404 myDlg->myMeshBtn->setChecked(false);
405 myDlg->myElemGeomBtn->setChecked(false);
406 onActivateObject( _NODE_GEOM ); // install filter
411 //================================================================================
413 * \brief Creates selection filter
414 * \param theId - identifier of current selection widget
415 * \retval SUIT_SelectionFilter* - pointer to the created filter or null
417 * Creates selection filter in accordance with identifier of current selection widget
419 //================================================================================
420 SUIT_SelectionFilter* SMESHGUI_GroupOnShapeOp::createFilter( const int theId ) const
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 );
427 return ( SUIT_SelectionFilter*) 0;
429 //================================================================================
431 * \brief Updates dialog's look and feel
433 * Virtual method redefined from the base class updates dialog's look and feel
435 //================================================================================
436 void SMESHGUI_GroupOnShapeOp::selectionDone()
438 QStringList names, ids;
439 LightApp_Dialog::TypesList types;
440 selected( names, types, ids );
441 int nbSelected = names.size();
443 if ( myDlg->myMeshBtn->isChecked() ) // mesh selected
445 myDlg->myMeshLine->setText("");
447 if ( nbSelected == 1 ) {
448 myDlg->myMeshLine->setText( names.front() );
449 myMeshID = ids.front();
451 myDlg->myElemGeomList->clear();
452 myDlg->myElemGeomBtn->setEnabled( nbSelected == 1 );
453 myDlg->myNodeGeomList->clear();
454 myDlg->myNodeGeomBtn->setEnabled( nbSelected == 1 );
455 myDlg->myElemGeomBtn->click();
459 // Filter off inappropriate shapes
461 QStringList goodNames, goodIds;
462 if (nbSelected > 0) {
464 if (_PTR(Study) aStudy = SMESH::getStudy()) {
466 if (_PTR(SObject) meshSO = aStudy->FindObjectID( myMeshID.toUtf8().data() ))
469 GEOM::GEOM_Object_var mainGeom = SMESH::GetGeom( meshSO );
471 QStringList::iterator name = names.begin(), id = ids.begin(), idEnd = ids.end();
472 for (; id != idEnd; ++id, ++name )
474 if ( goodIds.contains( *id ))
477 _PTR(SObject) shapeSO = aStudy->FindObjectID( id->toUtf8().data() );
478 GEOM::GEOM_Object_var subGeom = SMESH::GetGeom( shapeSO );
479 if ( SMESH::ContainsSubShape( mainGeom, subGeom ))
481 goodIds.append( *id );
482 goodNames.append( *name );
489 if ( myDlg->myElemGeomBtn->isChecked() ) // elem geometry selection
491 myDlg->myElemGeomList->clear();
492 myDlg->myElemGeomList->addItems( goodNames );
493 myElemGeoIDs = goodIds;
495 else if ( myDlg->myNodeGeomBtn->isChecked() ) // Node geometry selection
497 myDlg->myNodeGeomList->clear();
498 myDlg->myNodeGeomList->addItems( goodNames );
499 myNodeGeoIDs = goodIds;
502 // enable/disable Apply, which can change at selection
503 myDlg->updateButtons();