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>
42 #include <SALOMEconfig.h>
43 #include CORBA_SERVER_HEADER(SMESH_Mesh)
44 #include CORBA_SERVER_HEADER(SMESH_Group)
46 #include <qgroupbox.h>
50 #include <qpushbutton.h>
52 #include <qlineedit.h>
54 enum { _MESH, _ELEM_GEOM, _NODE_GEOM };
56 SMESHGUI_GroupOnShapeDlg::SMESHGUI_GroupOnShapeDlg()
57 : SMESHGUI_Dialog( 0, false, true )
59 QPixmap image (resourceMgr()->loadPixmap("SMESH", tr("ICON_SELECT")));
61 QGroupBox* aGrp = new QGroupBox( 3, Qt::Horizontal, mainFrame() );
62 aGrp->setFrameStyle( QFrame::NoFrame );
63 aGrp->setInsideMargin( 0 );
66 //new QLabel( tr( "SMESH_NAME" ), aGrp ); new QLabel( "", aGrp );
67 //myGrpNameLine = new QLineEdit( aGrp, "myGrpNameLine" );
70 new QLabel( tr( "SMESH_OBJECT_MESH" ), aGrp );
71 myMeshBtn = new QPushButton( aGrp, "myMeshBtn");
72 myMeshBtn->setToggleButton(true);
73 myMeshBtn->setPixmap(image);
74 myMeshLine = new QLineEdit( aGrp, "myMeshLine" );
75 myMeshLine->setReadOnly(true);
79 QGroupBox* elemsGrp = new QGroupBox( 1, Qt::Horizontal, tr( "SMESH_ELEMENTS" ), mainFrame() );
80 QFrame* elemFr = new QFrame(elemsGrp, "elemFr");
82 QLabel* label = new QLabel( tr( "SMESH_OBJECT_GEOM" ), elemFr );
83 myElemGeomBtn = new QPushButton( elemFr, "myElemGeomBtn");
84 myElemGeomBtn->setToggleButton(true);
85 myElemGeomBtn->setPixmap(image);
86 myElemGeomList = new QListBox( elemFr, "myElemGeomList" );
87 myElemGeomList->setSelectionMode(QListBox::NoSelection);
89 QGridLayout* elemLay = new QGridLayout(elemFr, 2, 3);
90 elemLay->setSpacing(6);
91 elemLay->setAutoAdd(false);
92 elemLay->setRowStretch( 1, 1 );
93 elemLay->addWidget( label, 0, 0 );
94 elemLay->addWidget( myElemGeomBtn, 0, 1 );
95 elemLay->addMultiCellWidget(myElemGeomList, 0, 1, 2, 2);
99 QGroupBox* nodesGrp = new QGroupBox( 1, Qt::Horizontal, tr( "SMESH_NODES" ), mainFrame() );
100 QFrame* nodeFr = new QFrame(nodesGrp, "nodeFr");
102 label = new QLabel( tr( "SMESH_OBJECT_GEOM" ), nodeFr );
103 myNodeGeomBtn = new QPushButton( nodeFr, "myNodeGeomBtn");
104 myNodeGeomBtn->setToggleButton(true);
105 myNodeGeomBtn->setPixmap(image);
106 myNodeGeomList = new QListBox( nodeFr, "myNodeGeomList" );
107 myNodeGeomList->setSelectionMode(QListBox::NoSelection);
109 QGridLayout* nodeLay = new QGridLayout(nodeFr, 2, 3);
110 nodeLay->setSpacing(6);
111 nodeLay->setAutoAdd(false);
112 nodeLay->setRowStretch( 1, 1 );
113 nodeLay->addWidget( label, 0, 0 );
114 nodeLay->addWidget( myNodeGeomBtn, 0, 1 );
115 nodeLay->addMultiCellWidget(myNodeGeomList, 0, 1, 2, 2);
118 QVBoxLayout* aLay = new QVBoxLayout( mainFrame(), 0, 5 );
119 aLay->addWidget( aGrp );
120 aLay->addWidget( elemsGrp );
121 aLay->addWidget( nodesGrp );
123 setCaption( tr( "SMESH_CREATE_GROUP_FROM_GEOM" ) );
126 //================================================================================
128 * \brief slot to enable/diable [Apply]
130 //================================================================================
132 void SMESHGUI_GroupOnShapeDlg::updateButtons()
135 /*!myGrpNameLine->text().isEmpty() &&*/ myElemGeomList->count() + myNodeGeomList->count();
137 button(Apply)->setEnabled( enable );
138 button(OK)->setEnabled( enable );
141 //================================================================================
143 * \brief initialization
145 //================================================================================
147 void SMESHGUI_GroupOnShapeDlg::init()
149 //myGrpNameLine->setText("");
151 myMeshBtn->setOn( true );
152 myMeshLine->setText("");
154 myElemGeomBtn->setOn(false);
155 myElemGeomBtn->setEnabled(false);
156 myElemGeomList->clear();
157 myNodeGeomBtn->setOn(false);
158 myNodeGeomBtn->setEnabled(false);
159 myNodeGeomList->clear();
164 //================================================================================
166 * \brief operation constructor
168 //================================================================================
170 SMESHGUI_GroupOnShapeOp::SMESHGUI_GroupOnShapeOp()
171 : SMESHGUI_SelectionOp(ActorSelection),
174 myHelpFileName = "creating_groups_page.html";
177 SMESHGUI_GroupOnShapeOp::~SMESHGUI_GroupOnShapeOp()
182 //================================================================================
184 * \brief Gets dialog of this operation
185 * \retval LightApp_Dialog* - pointer to dialog of this operation
187 //================================================================================
189 LightApp_Dialog* SMESHGUI_GroupOnShapeOp::dlg() const
194 //================================================================================
196 * \brief return type of mesh group by geom object
198 //================================================================================
200 static SMESH::ElementType elementType(GEOM::GEOM_Object_var& geom)
202 if ( !geom->_is_nil() ) {
203 switch ( geom->GetShapeType() ) {
204 case GEOM::VERTEX: return SMESH::NODE;
205 case GEOM::EDGE: return SMESH::EDGE;
206 case GEOM::WIRE: return SMESH::EDGE;
207 case GEOM::FACE: return SMESH::FACE;
208 case GEOM::SHELL: return SMESH::FACE;
209 case GEOM::SOLID: return SMESH::VOLUME;
210 case GEOM::COMPSOLID:return SMESH::VOLUME;
211 case GEOM::COMPOUND: break;
212 default: return SMESH::ALL;
214 _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
215 GEOM::GEOM_IShapesOperations_var aShapeOp =
216 SMESH::GetGEOMGen()->GetIShapesOperations(aStudy->StudyId());
218 if ( geom->GetType() == 37 ) { // geom group
219 GEOM::GEOM_IGroupOperations_var aGroupOp =
220 SMESH::GetGEOMGen()->GetIGroupOperations(aStudy->StudyId());
221 if ( !aGroupOp->_is_nil() ) {
222 GEOM::GEOM_Object_var mainShape = aGroupOp->GetMainShape( geom );
223 GEOM::ListOfLong_var ids = aGroupOp->GetObjects( geom );
224 if ( ids->length() && !mainShape->_is_nil() && !aShapeOp->_is_nil() ) {
225 GEOM::GEOM_Object_var member = aShapeOp->GetSubShape( mainShape, ids[0] );
226 return elementType( member );
230 else if ( !aShapeOp->_is_nil() ) { // just a compoud shape
231 GEOM::ListOfLong_var ids = aShapeOp->SubShapeAllIDs( geom, GEOM::SHAPE, false );
232 if ( ids->length() ) {
233 GEOM::GEOM_Object_var member = aShapeOp->GetSubShape( geom, ids[0] );
234 return elementType( member );
241 //================================================================================
243 * \brief initialization
245 //================================================================================
247 void SMESHGUI_GroupOnShapeOp::init()
250 myElemGeoIDs.clear();
251 myNodeGeoIDs.clear();
254 removeCustomFilters();
255 onActivateObject( _MESH ); // install filter
258 //================================================================================
260 * \brief start operation
262 //================================================================================
264 void SMESHGUI_GroupOnShapeOp::startOperation()
268 myDlg = new SMESHGUI_GroupOnShapeDlg();
269 connect(myDlg->myMeshBtn, SIGNAL(clicked()), this, SLOT(onButtonClick()));
270 connect(myDlg->myElemGeomBtn, SIGNAL(clicked()), this, SLOT(onButtonClick()));
271 connect(myDlg->myNodeGeomBtn, SIGNAL(clicked()), this, SLOT(onButtonClick()));
272 //connect(myDlg->myGrpNameLine, SIGNAL(textChanged(const QString&)),myDlg,SLOT(updateButtons()));
274 SMESHGUI_SelectionOp::startOperation();
280 //================================================================================
282 * \brief create groups
284 //================================================================================
286 bool SMESHGUI_GroupOnShapeOp::onApply()
288 SUIT_OverrideCursor aWaitCursor;
294 _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
295 if ( !aStudy ) return false;
298 _PTR(SObject) meshSO = aStudy->FindObjectID( myMeshID );
299 SMESH::SMESH_Mesh_var mesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( meshSO );
300 if ( mesh->_is_nil() ) return false;
302 // names of all existing groups
303 // QStringList groupNames;
304 // QString givenName = myDlg->myGrpNameLine->text();
305 // if ( !givenName.isEmpty() ) {
306 // SMESH::ListOfGroups_var groups = mesh->GetGroups();
307 // for ( int i = 0; i < groups->length(); ++i ) {
308 // CORBA::String_var name = groups[i]->GetName();
309 // groupNames.append( name.in() );
314 SMESH::SMESH_GroupOnGeom_var group;
315 for ( int isNode = 0; isNode < 2; ++isNode ) // elems and then nodes
317 QStringList::iterator geomID = isNode ? myNodeGeoIDs.begin() : myElemGeoIDs.begin();
318 QStringList::iterator geomEnd = isNode ? myNodeGeoIDs.end() : myElemGeoIDs.end();
320 for (int i = 0 ; geomID != geomEnd; ++geomID, ++i )
323 _PTR(SObject) geomSO = aStudy->FindObjectID( *geomID );
324 GEOM::GEOM_Object_var geom = SMESH::SObjectToInterface<GEOM::GEOM_Object>(geomSO);
325 if ( geom->_is_nil() ) continue;
328 SMESH::ElementType elemType = isNode ? SMESH::NODE : elementType( geom );
329 if ( elemType == SMESH::ALL )
334 //if ( givenName.isEmpty() ) { // use shape name
335 name = isNode ? myDlg->myNodeGeomList->text(i) : myDlg->myElemGeomList->text(i);
337 // else { // make a unique name
340 // if ( myNodeGeoIDs.size() + myElemGeoIDs.size() > 1 )
341 // name += "_" + QString::number(++nb);
342 // while ( groupNames.contains( name ))
343 // name = givenName + "_" + QString::number(++nb);
344 // groupNames.append( name );
346 //printf( "apply() %s %s\n", (*geomID).latin1(), name.latin1() );
347 group = mesh->CreateGroupFromGEOM( elemType, name, geom );
350 update( UF_ObjBrowser | UF_Model );
354 return !group->_is_nil();
357 //================================================================================
359 * \brief slot connected to selection buttons
361 //================================================================================
363 void SMESHGUI_GroupOnShapeOp::onButtonClick()
365 removeCustomFilters();
367 if ( sender() == myDlg->myMeshBtn && myDlg->myMeshBtn->isOn() )
369 myDlg->myElemGeomBtn->setOn(false);
370 myDlg->myNodeGeomBtn->setOn(false);
371 onActivateObject( _MESH ); // install filter
373 else if ( sender() == myDlg->myElemGeomBtn && myDlg->myElemGeomBtn->isOn() )
375 myDlg->myMeshBtn->setOn(false);
376 myDlg->myNodeGeomBtn->setOn(false);
377 onActivateObject( _ELEM_GEOM ); // install filter
379 else if ( sender() == myDlg->myNodeGeomBtn && myDlg->myNodeGeomBtn->isOn() )
381 myDlg->myMeshBtn->setOn(false);
382 myDlg->myElemGeomBtn->setOn(false);
383 onActivateObject( _NODE_GEOM ); // install filter
388 //================================================================================
390 * \brief Creates selection filter
391 * \param theId - identifier of current selection widget
392 * \retval SUIT_SelectionFilter* - pointer to the created filter or null
394 * Creates selection filter in accordance with identifier of current selection widget
396 //================================================================================
397 SUIT_SelectionFilter* SMESHGUI_GroupOnShapeOp::createFilter( const int theId ) const
399 if ( theId == _ELEM_GEOM || theId == _NODE_GEOM )
400 return new GEOM_SelectionFilter( (SalomeApp_Study*)study(), true );
401 else if ( theId == _MESH )
402 return new SMESH_TypeFilter( MESH );
404 return ( SUIT_SelectionFilter*) 0;
406 //================================================================================
408 * \brief Updates dialog's look and feel
410 * Virtual method redefined from the base class updates dialog's look and feel
412 //================================================================================
413 void SMESHGUI_GroupOnShapeOp::selectionDone()
415 QStringList names, ids;
416 LightApp_Dialog::TypesList types;
417 selected( names, types, ids );
418 int nbSelected = names.size();
420 if ( myDlg->myMeshBtn->isOn() ) // mesh selected
422 myDlg->myMeshLine->setText("");
424 if ( nbSelected == 1 ) {
425 myDlg->myMeshLine->setText( names.front() );
426 myMeshID = ids.front();
428 myDlg->myElemGeomList->clear();
429 myDlg->myElemGeomBtn->setEnabled( nbSelected == 1 );
430 myDlg->myNodeGeomList->clear();
431 myDlg->myNodeGeomBtn->setEnabled( nbSelected == 1 );
435 // Filter off inappropriate shapes
437 QStringList goodNames, goodIds;
438 if (nbSelected > 0) {
440 if (_PTR(Study) aStudy = SMESH::GetActiveStudyDocument()) {
442 if (_PTR(SObject) meshSO = aStudy->FindObjectID( myMeshID )) {
444 _PTR(SObject) anObj, shapeToMesh;
445 if (meshSO->FindSubObject(1, anObj) && anObj->ReferencedObject(shapeToMesh)) {
447 QStringList::iterator name = names.begin(), id = ids.begin(), idEnd = ids.end();
448 for (; id != idEnd; ++id, ++name ) {
450 if (_PTR(SObject) shapeSO = aStudy->FindObjectID( *id )) {
451 // check if shape SO is a child of shape to mesh
452 while ( shapeSO && shapeSO->GetID() != shapeToMesh->GetID() )
453 if ( shapeSO->Depth() < 2 )
456 shapeSO = shapeSO->GetFather();
458 //printf( "selectionDone() %s %s\n", (*id).latin1(), (*name).latin1() );
459 if ( !goodIds.contains( *id )) {
460 goodIds.append( *id );
461 goodNames.append( *name );
471 if ( myDlg->myElemGeomBtn->isOn() ) // elem geomerty selection
473 myDlg->myElemGeomList->clear();
474 myDlg->myElemGeomList->insertStringList( goodNames );
475 myElemGeoIDs = goodIds;
477 else if ( myDlg->myNodeGeomBtn->isOn() ) // Node geomerty selection
479 myDlg->myNodeGeomList->clear();
480 myDlg->myNodeGeomList->insertStringList( goodNames );
481 myNodeGeoIDs = goodIds;
484 // enable/diable Apply, which can change at selection
485 myDlg->updateButtons();