1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // SMESH SMESHGUI : GUI for SMESH component
23 // File : SMESHGUI_GroupOnShapeDlg.cxx
24 // Created : Wed Sep 17 18:36:51 2008
25 // Author : Edward AGAPOV (eap)
29 #include "SMESHGUI_GroupOnShapeDlg.h"
31 #include "SMESH_TypeFilter.hxx"
32 #include "SMESHGUI_Utils.h"
33 #include "SMESHGUI_GEOMGenUtils.h"
35 #include <GeometryGUI.h>
36 #include <GEOM_SelectionFilter.h>
38 #include <SUIT_Session.h>
39 #include <SUIT_OverrideCursor.h>
40 #include <LightApp_UpdateFlags.h>
41 #include <SUIT_ResourceMgr.h>
43 #include <SALOMEconfig.h>
44 #include CORBA_SERVER_HEADER(SMESH_Mesh)
45 #include CORBA_SERVER_HEADER(SMESH_Group)
51 #include <QPushButton>
52 #include <QListWidget>
58 enum { _MESH, _ELEM_GEOM, _NODE_GEOM };
60 SMESHGUI_GroupOnShapeDlg::SMESHGUI_GroupOnShapeDlg()
61 : SMESHGUI_Dialog( 0, false, true )
63 QPixmap image (resourceMgr()->loadPixmap("SMESH", tr("ICON_SELECT")));
66 //QLabel* nameLabel = new QLabel( tr( "SMESH_NAME" ), mainFrame() );
67 //myGrpNameLine = new QLineEdit( mainFrame() );
70 QLabel* meshLabel = new QLabel( tr( "SMESH_OBJECT_MESH" ), mainFrame() );
71 myMeshBtn = new QPushButton( mainFrame() );
72 myMeshBtn->setCheckable(true);
73 myMeshBtn->setIcon(image);
74 myMeshLine = new QLineEdit( mainFrame() );
75 myMeshLine->setReadOnly(true);
79 QGroupBox* elemsGrp = new QGroupBox( tr( "SMESH_ELEMENTS" ), mainFrame() );
80 QLabel* label = new QLabel( tr( "SMESH_GEOM" ), elemsGrp );
81 myElemGeomBtn = new QPushButton( elemsGrp );
82 myElemGeomBtn->setCheckable(true);
83 myElemGeomBtn->setIcon(image);
84 myElemGeomList = new QListWidget( elemsGrp );
85 myElemGeomList->setSelectionMode(QListWidget::NoSelection);
87 QGridLayout* elemLay = new QGridLayout(elemsGrp);
88 elemLay->setSpacing( SPACING );
89 elemLay->setMargin( MARGIN );
90 elemLay->setRowStretch( 1, 1 );
91 elemLay->addWidget( label, 0, 0 );
92 elemLay->addWidget( myElemGeomBtn, 0, 1 );
93 elemLay->addWidget( myElemGeomList, 0, 2, 2, 1);
97 QGroupBox* nodesGrp = new QGroupBox( tr( "SMESH_NODES" ), mainFrame() );
99 label = new QLabel( tr( "SMESH_GEOM" ), nodesGrp );
100 myNodeGeomBtn = new QPushButton( nodesGrp );
101 myNodeGeomBtn->setCheckable(true);
102 myNodeGeomBtn->setIcon(image);
103 myNodeGeomList = new QListWidget( nodesGrp );
104 myNodeGeomList->setSelectionMode(QListWidget::NoSelection);
106 QGridLayout* nodeLay = new QGridLayout(nodesGrp);
107 nodeLay->setSpacing( SPACING );
108 nodeLay->setMargin( MARGIN );
109 nodeLay->setRowStretch( 1, 1 );
110 nodeLay->addWidget( label, 0, 0 );
111 nodeLay->addWidget( myNodeGeomBtn, 0, 1 );
112 nodeLay->addWidget(myNodeGeomList, 0, 2, 2, 1);
115 QGridLayout* aLay = new QGridLayout( mainFrame());
116 aLay->setSpacing( SPACING );
117 aLay->setMargin( MARGIN );
118 //aLay->addWidget( nameLabel, 0, 0 );
119 //aLay->addWidget( myGrpNameLine, 0, 2 );
120 aLay->addWidget( meshLabel, 1, 0 );
121 aLay->addWidget( myMeshBtn, 1, 1 );
122 aLay->addWidget( myMeshLine,1, 2 );
123 aLay->addWidget( elemsGrp, 2, 1, 1, 3 );
124 aLay->addWidget( nodesGrp, 3, 1, 1, 3 );
126 setWindowTitle( tr( "SMESH_CREATE_GROUP_FROM_GEOM" ) );
129 SMESHGUI_GroupOnShapeDlg::~SMESHGUI_GroupOnShapeDlg()
133 //================================================================================
135 * \brief slot to enable/diable [Apply]
137 //================================================================================
139 void SMESHGUI_GroupOnShapeDlg::updateButtons()
142 /*!myGrpNameLine->text().isEmpty() &&*/ myElemGeomList->count() + myNodeGeomList->count();
144 button(Apply)->setEnabled( enable );
145 button(OK)->setEnabled( enable );
148 //================================================================================
150 * \brief initialization
152 //================================================================================
154 void SMESHGUI_GroupOnShapeDlg::init()
156 //myGrpNameLine->setText("");
158 myMeshBtn->setChecked( true );
159 myMeshLine->setText("");
161 myElemGeomBtn->setChecked(false);
162 myElemGeomBtn->setEnabled(false);
163 myElemGeomList->clear();
164 myNodeGeomBtn->setChecked(false);
165 myNodeGeomBtn->setEnabled(false);
166 myNodeGeomList->clear();
171 //================================================================================
173 * \brief operation constructor
175 //================================================================================
177 SMESHGUI_GroupOnShapeOp::SMESHGUI_GroupOnShapeOp()
178 : SMESHGUI_SelectionOp(ActorSelection),
181 myHelpFileName = "creating_groups_page.html";
184 SMESHGUI_GroupOnShapeOp::~SMESHGUI_GroupOnShapeOp()
189 //================================================================================
191 * \brief Gets dialog of this operation
192 * \retval LightApp_Dialog* - pointer to dialog of this operation
194 //================================================================================
196 LightApp_Dialog* SMESHGUI_GroupOnShapeOp::dlg() const
201 //================================================================================
203 * \brief return type of mesh group by geom object
205 //================================================================================
207 static SMESH::ElementType elementType(GEOM::GEOM_Object_var& geom)
209 if ( !geom->_is_nil() ) {
210 switch ( geom->GetShapeType() ) {
211 case GEOM::VERTEX: return SMESH::NODE;
212 case GEOM::EDGE: return SMESH::EDGE;
213 case GEOM::WIRE: return SMESH::EDGE;
214 case GEOM::FACE: return SMESH::FACE;
215 case GEOM::SHELL: return SMESH::FACE;
216 case GEOM::SOLID: return SMESH::VOLUME;
217 case GEOM::COMPSOLID:return SMESH::VOLUME;
218 case GEOM::COMPOUND: break;
219 default: return SMESH::ALL;
221 _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
222 GEOM::GEOM_IShapesOperations_var aShapeOp =
223 SMESH::GetGEOMGen()->GetIShapesOperations(aStudy->StudyId());
225 if ( geom->GetType() == 37 ) { // geom group
226 GEOM::GEOM_IGroupOperations_var aGroupOp =
227 SMESH::GetGEOMGen()->GetIGroupOperations(aStudy->StudyId());
228 if ( !aGroupOp->_is_nil() ) {
229 GEOM::GEOM_Object_var mainShape = aGroupOp->GetMainShape( geom );
230 GEOM::ListOfLong_var ids = aGroupOp->GetObjects( geom );
231 if ( ids->length() && !mainShape->_is_nil() && !aShapeOp->_is_nil() ) {
232 GEOM::GEOM_Object_var member = aShapeOp->GetSubShape( mainShape, ids[0] );
233 return elementType( member );
237 else if ( !aShapeOp->_is_nil() ) { // just a compoud shape
238 GEOM::ListOfLong_var ids = aShapeOp->SubShapeAllIDs( geom, GEOM::SHAPE, false );
239 if ( ids->length() ) {
240 GEOM::GEOM_Object_var member = aShapeOp->GetSubShape( geom, ids[0] );
241 return elementType( member );
248 //================================================================================
250 * \brief initialization
252 //================================================================================
254 void SMESHGUI_GroupOnShapeOp::init()
257 myElemGeoIDs.clear();
258 myNodeGeoIDs.clear();
261 removeCustomFilters();
262 onActivateObject( _MESH ); // install filter
265 //================================================================================
267 * \brief start operation
269 //================================================================================
271 void SMESHGUI_GroupOnShapeOp::startOperation()
275 myDlg = new SMESHGUI_GroupOnShapeDlg();
276 connect(myDlg->myMeshBtn, SIGNAL(clicked()), this, SLOT(onButtonClick()));
277 connect(myDlg->myElemGeomBtn, SIGNAL(clicked()), this, SLOT(onButtonClick()));
278 connect(myDlg->myNodeGeomBtn, SIGNAL(clicked()), this, SLOT(onButtonClick()));
279 //connect(myDlg->myGrpNameLine, SIGNAL(textChanged(const QString&)),myDlg,SLOT(updateButtons()));
281 SMESHGUI_SelectionOp::startOperation();
287 //================================================================================
289 * \brief create groups
291 //================================================================================
293 bool SMESHGUI_GroupOnShapeOp::onApply()
295 SUIT_OverrideCursor aWaitCursor;
301 _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
302 if ( !aStudy ) return false;
305 _PTR(SObject) meshSO = aStudy->FindObjectID( myMeshID.toLatin1().data() );
306 SMESH::SMESH_Mesh_var mesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( meshSO );
307 if ( mesh->_is_nil() ) return false;
309 // names of all existing groups
310 // QStringList groupNames;
311 // QString givenName = myDlg->myGrpNameLine->text();
312 // if ( !givenName.isEmpty() ) {
313 // SMESH::ListOfGroups_var groups = mesh->GetGroups();
314 // for ( int i = 0; i < groups->length(); ++i ) {
315 // CORBA::String_var name = groups[i]->GetName();
316 // groupNames.append( name.in() );
321 SMESH::SMESH_GroupOnGeom_var group;
322 for ( int isNode = 0; isNode < 2; ++isNode ) // elems and then nodes
324 QStringList::iterator geomID = isNode ? myNodeGeoIDs.begin() : myElemGeoIDs.begin();
325 QStringList::iterator geomEnd = isNode ? myNodeGeoIDs.end() : myElemGeoIDs.end();
327 for ( int i = 0; geomID != geomEnd; ++geomID, ++i )
330 _PTR(SObject) geomSO = aStudy->FindObjectID( geomID->toLatin1().data() );
331 GEOM::GEOM_Object_var geom = SMESH::SObjectToInterface<GEOM::GEOM_Object>(geomSO);
332 if ( geom->_is_nil() ) continue;
335 SMESH::ElementType elemType = isNode ? SMESH::NODE : elementType( geom );
336 if ( elemType == SMESH::ALL )
339 // make a unique name
341 isNode ? myDlg->myNodeGeomList->item(i)->text() : myDlg->myElemGeomList->item(i)->text();
343 // QString name = myDlg->myGrpNameLine->text() + "_" + QString::number(nb);
344 // while ( groupNames.contains( name ))
345 // name = myDlg->myGrpNameLine->text() + "_" + QString::number(++nb);
346 // groupNames.append( name );
348 //printf( "apply() %s %s\n", (*geomID).latin1(), name.latin1() );
349 group = mesh->CreateGroupFromGEOM( elemType, name.toLatin1().data(), geom );
352 update( UF_ObjBrowser | UF_Model );
356 return !group->_is_nil();
359 //================================================================================
361 * \brief slot connected to selection buttons
363 //================================================================================
365 void SMESHGUI_GroupOnShapeOp::onButtonClick()
367 removeCustomFilters();
369 if ( sender() == myDlg->myMeshBtn && myDlg->myMeshBtn->isChecked() )
371 myDlg->myElemGeomBtn->setChecked(false);
372 myDlg->myNodeGeomBtn->setChecked(false);
373 onActivateObject( _MESH ); // install filter
375 else if ( sender() == myDlg->myElemGeomBtn && myDlg->myElemGeomBtn->isChecked() )
377 myDlg->myMeshBtn->setChecked(false);
378 myDlg->myNodeGeomBtn->setChecked(false);
379 onActivateObject( _ELEM_GEOM ); // install filter
381 else if ( sender() == myDlg->myNodeGeomBtn && myDlg->myNodeGeomBtn->isChecked() )
383 myDlg->myMeshBtn->setChecked(false);
384 myDlg->myElemGeomBtn->setChecked(false);
385 onActivateObject( _NODE_GEOM ); // install filter
390 //================================================================================
392 * \brief Creates selection filter
393 * \param theId - identifier of current selection widget
394 * \retval SUIT_SelectionFilter* - pointer to the created filter or null
396 * Creates selection filter in accordance with identifier of current selection widget
398 //================================================================================
399 SUIT_SelectionFilter* SMESHGUI_GroupOnShapeOp::createFilter( const int theId ) const
401 if ( theId == _ELEM_GEOM || theId == _NODE_GEOM )
402 return new GEOM_SelectionFilter( (SalomeApp_Study*)study(), true );
403 else if ( theId == _MESH )
404 return new SMESH_TypeFilter( MESH );
406 return ( SUIT_SelectionFilter*) 0;
408 //================================================================================
410 * \brief Updates dialog's look and feel
412 * Virtual method redefined from the base class updates dialog's look and feel
414 //================================================================================
415 void SMESHGUI_GroupOnShapeOp::selectionDone()
417 QStringList names, ids;
418 LightApp_Dialog::TypesList types;
419 selected( names, types, ids );
420 int nbSelected = names.size();
422 if ( myDlg->myMeshBtn->isChecked() ) // mesh selected
424 myDlg->myMeshLine->setText("");
426 if ( nbSelected == 1 ) {
427 myDlg->myMeshLine->setText( names.front() );
428 myMeshID = ids.front();
430 myDlg->myElemGeomList->clear();
431 myDlg->myElemGeomBtn->setEnabled( nbSelected == 1 );
432 myDlg->myNodeGeomList->clear();
433 myDlg->myNodeGeomBtn->setEnabled( nbSelected == 1 );
434 myDlg->myElemGeomBtn->click();
438 // Filter off inappropriate shapes
440 QStringList goodNames, goodIds;
441 if (nbSelected > 0) {
443 if (_PTR(Study) aStudy = SMESH::GetActiveStudyDocument()) {
445 if (_PTR(SObject) meshSO = aStudy->FindObjectID( myMeshID.toLatin1().data() )) {
447 _PTR(SObject) anObj, shapeToMesh;
448 if (meshSO->FindSubObject(1, anObj) && anObj->ReferencedObject(shapeToMesh)) {
450 QStringList::iterator name = names.begin(), id = ids.begin(), idEnd = ids.end();
451 for (; id != idEnd; ++id, ++name ) {
453 if (_PTR(SObject) shapeSO = aStudy->FindObjectID( id->toLatin1().data() )) {
454 // check if shape SO is a child of shape to mesh
455 while ( shapeSO && shapeSO->GetID() != shapeToMesh->GetID() )
456 if ( shapeSO->Depth() < 2 )
459 shapeSO = shapeSO->GetFather();
461 //printf( "selectionDone() %s %s\n", (*id).latin1(), (*name).latin1() );
462 if ( !goodIds.contains( *id )) {
463 goodIds.append( *id );
464 goodNames.append( *name );
474 if ( myDlg->myElemGeomBtn->isChecked() ) // elem geomerty selection
476 myDlg->myElemGeomList->clear();
477 myDlg->myElemGeomList->addItems( goodNames );
478 myElemGeoIDs = goodIds;
480 else if ( myDlg->myNodeGeomBtn->isChecked() ) // Node geomerty selection
482 myDlg->myNodeGeomList->clear();
483 myDlg->myNodeGeomList->addItems( goodNames );
484 myNodeGeoIDs = goodIds;
487 // enable/diable Apply, which can change at selection
488 myDlg->updateButtons();