Salome HOME
PAL15429 Computation of the mesh, based on "014.brep" via Tetrahedron(NETGEN), is...
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_GroupOnShapeDlg.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
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)
26 // Module    : SMESH
27 // IDL Headers
28 //
29 #include "SMESHGUI_GroupOnShapeDlg.h"
30
31 #include "SMESH_TypeFilter.hxx"
32 #include "SMESHGUI_Utils.h"
33 #include "SMESHGUI_GEOMGenUtils.h"
34
35 #include <GeometryGUI.h>
36 #include <GEOM_SelectionFilter.h>
37
38 #include <SUIT_Session.h>
39 #include <SUIT_OverrideCursor.h>
40 #include <LightApp_UpdateFlags.h>
41
42 #include <SALOMEconfig.h>
43 #include CORBA_SERVER_HEADER(SMESH_Mesh)
44 #include CORBA_SERVER_HEADER(SMESH_Group)
45
46 #include <qgroupbox.h>
47 #include <qlayout.h>
48 #include <qframe.h>
49 #include <qlabel.h>
50 #include <qpushbutton.h>
51 #include <qlistbox.h>
52 #include <qlineedit.h>
53
54 enum { _MESH, _ELEM_GEOM, _NODE_GEOM };
55
56 SMESHGUI_GroupOnShapeDlg::SMESHGUI_GroupOnShapeDlg()
57   : SMESHGUI_Dialog( 0, false, true )
58 {
59   QPixmap image (resourceMgr()->loadPixmap("SMESH", tr("ICON_SELECT")));
60
61   QGroupBox* aGrp = new QGroupBox( 3, Qt::Horizontal, mainFrame() );
62   aGrp->setFrameStyle( QFrame::NoFrame );
63   aGrp->setInsideMargin( 0 );
64
65   // Name
66   //new QLabel( tr( "SMESH_NAME" ), aGrp ); new QLabel( "", aGrp );
67   //myGrpNameLine = new QLineEdit( aGrp, "myGrpNameLine" );
68
69   // Mesh
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);
76
77   // Elem geom
78
79   QGroupBox* elemsGrp = new QGroupBox( 1, Qt::Horizontal, tr( "SMESH_ELEMENTS" ), mainFrame() );
80   QFrame* elemFr = new QFrame(elemsGrp, "elemFr");
81
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);
88
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);
96
97   // Node geom
98
99   QGroupBox* nodesGrp = new QGroupBox( 1, Qt::Horizontal, tr( "SMESH_NODES" ), mainFrame() );
100   QFrame* nodeFr = new QFrame(nodesGrp, "nodeFr");
101
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);
108
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);
116
117   // Fill layout
118   QVBoxLayout* aLay = new QVBoxLayout( mainFrame(), 0, 5 );
119   aLay->addWidget( aGrp );
120   aLay->addWidget( elemsGrp );
121   aLay->addWidget( nodesGrp );
122
123   setCaption( tr( "SMESH_CREATE_GROUP_FROM_GEOM" ) );
124 }
125
126 //================================================================================
127 /*!
128  * \brief slot to enable/diable [Apply]
129  */
130 //================================================================================
131
132 void SMESHGUI_GroupOnShapeDlg::updateButtons()
133 {
134   bool enable =
135     /*!myGrpNameLine->text().isEmpty() &&*/ myElemGeomList->count() + myNodeGeomList->count();
136
137   button(Apply)->setEnabled( enable );
138   button(OK)->setEnabled( enable );
139 }
140
141 //================================================================================
142 /*!
143  * \brief initialization
144  */
145 //================================================================================
146
147 void SMESHGUI_GroupOnShapeDlg::init()
148 {
149   //myGrpNameLine->setText("");
150
151   myMeshBtn->setOn( true );
152   myMeshLine->setText("");
153
154   myElemGeomBtn->setOn(false);
155   myElemGeomBtn->setEnabled(false);
156   myElemGeomList->clear();
157   myNodeGeomBtn->setOn(false);
158   myNodeGeomBtn->setEnabled(false);
159   myNodeGeomList->clear();
160
161   updateButtons();
162 }
163
164 //================================================================================
165 /*!
166  * \brief operation constructor
167  */
168 //================================================================================
169
170 SMESHGUI_GroupOnShapeOp::SMESHGUI_GroupOnShapeOp()
171   : SMESHGUI_SelectionOp(ActorSelection),
172     myDlg( 0 )
173 {
174   myHelpFileName = "creating_groups_page.html";
175 }
176
177 SMESHGUI_GroupOnShapeOp::~SMESHGUI_GroupOnShapeOp()
178 {
179   if ( myDlg )
180     delete myDlg;
181 }
182 //================================================================================
183 /*!
184  * \brief Gets dialog of this operation
185   * \retval LightApp_Dialog* - pointer to dialog of this operation
186 */
187 //================================================================================
188
189 LightApp_Dialog* SMESHGUI_GroupOnShapeOp::dlg() const
190 {
191   return myDlg;
192 }
193
194 //================================================================================
195 /*!
196  * \brief return type of mesh group by geom object
197  */
198 //================================================================================
199
200 static SMESH::ElementType elementType(GEOM::GEOM_Object_var& geom)
201 {
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;
213     }
214     _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
215     GEOM::GEOM_IShapesOperations_var aShapeOp =
216       SMESH::GetGEOMGen()->GetIShapesOperations(aStudy->StudyId());
217
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 );
227         }
228       }
229     }
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 );
235       }
236     }
237   }
238   return SMESH::ALL;
239 }
240
241 //================================================================================
242 /*!
243  * \brief initialization
244  */
245 //================================================================================
246
247 void SMESHGUI_GroupOnShapeOp::init()
248 {
249   myMeshID="";
250   myElemGeoIDs.clear();
251   myNodeGeoIDs.clear();
252
253   myDlg->init();
254   removeCustomFilters();
255   onActivateObject( _MESH ); // install filter
256 }
257
258 //================================================================================
259 /*!
260  * \brief start operation
261  */
262 //================================================================================
263
264 void SMESHGUI_GroupOnShapeOp::startOperation()
265 {
266   if (!myDlg)
267   {
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()));
273   }
274   SMESHGUI_SelectionOp::startOperation();
275
276   init();
277   myDlg->show();
278 }
279
280 //================================================================================
281 /*!
282  * \brief create groups
283  */
284 //================================================================================
285
286 bool SMESHGUI_GroupOnShapeOp::onApply()
287 {
288   SUIT_OverrideCursor aWaitCursor;
289
290   if (isStudyLocked())
291     return false;
292
293   // study
294   _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
295   if ( !aStudy ) return false;
296
297   // mesh
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;
301
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() );
310 //     }
311 //   }
312
313   // create groups
314   SMESH::SMESH_GroupOnGeom_var group;
315   for ( int isNode = 0; isNode < 2; ++isNode ) // elems and then nodes
316   {
317     QStringList::iterator geomID = isNode ? myNodeGeoIDs.begin() : myElemGeoIDs.begin();
318     QStringList::iterator geomEnd = isNode ? myNodeGeoIDs.end() : myElemGeoIDs.end();
319
320     for (int i = 0 ; geomID != geomEnd; ++geomID, ++i )
321     {
322       // selected geom
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;
326
327       // group type
328       SMESH::ElementType elemType = isNode ? SMESH::NODE : elementType( geom );
329       if ( elemType == SMESH::ALL )
330         continue;
331
332       // group name
333       QString name;
334       //if ( givenName.isEmpty() ) { // use shape name
335         name = isNode ? myDlg->myNodeGeomList->text(i) : myDlg->myElemGeomList->text(i);
336 //       }
337 //       else { // make a unique name
338 //         name = givenName;
339 //         int nb = 0;
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 );
345 //       }
346       //printf( "apply() %s %s\n", (*geomID).latin1(), name.latin1() );
347       group = mesh->CreateGroupFromGEOM( elemType, name, geom );
348     }
349   }
350   update( UF_ObjBrowser | UF_Model );
351
352   init();
353
354   return !group->_is_nil();
355 }
356
357 //================================================================================
358 /*!
359  * \brief slot connected to selection buttons
360  */
361 //================================================================================
362
363 void SMESHGUI_GroupOnShapeOp::onButtonClick()
364 {
365   removeCustomFilters();
366
367   if ( sender() == myDlg->myMeshBtn && myDlg->myMeshBtn->isOn() )
368   {
369     myDlg->myElemGeomBtn->setOn(false);
370     myDlg->myNodeGeomBtn->setOn(false);
371     onActivateObject( _MESH ); // install filter
372   }
373   else if ( sender() == myDlg->myElemGeomBtn && myDlg->myElemGeomBtn->isOn() )
374   {
375     myDlg->myMeshBtn->setOn(false);
376     myDlg->myNodeGeomBtn->setOn(false);
377     onActivateObject( _ELEM_GEOM ); // install filter
378   }
379   else if ( sender() == myDlg->myNodeGeomBtn && myDlg->myNodeGeomBtn->isOn() )
380   {
381     myDlg->myMeshBtn->setOn(false);
382     myDlg->myElemGeomBtn->setOn(false);
383     onActivateObject( _NODE_GEOM ); // install filter
384   }
385   //selectionDone();
386 }
387
388 //================================================================================
389 /*!
390  * \brief Creates selection filter
391   * \param theId - identifier of current selection widget
392   * \retval SUIT_SelectionFilter* - pointer to the created filter or null
393  *
394  * Creates selection filter in accordance with identifier of current selection widget
395  */
396 //================================================================================
397 SUIT_SelectionFilter* SMESHGUI_GroupOnShapeOp::createFilter( const int theId ) const
398 {
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 );
403   else
404     return ( SUIT_SelectionFilter*) 0;
405 }
406 //================================================================================
407 /*!
408  * \brief Updates dialog's look and feel
409  *
410  * Virtual method redefined from the base class updates dialog's look and feel
411  */
412 //================================================================================
413 void SMESHGUI_GroupOnShapeOp::selectionDone()
414 {
415   QStringList names, ids;
416   LightApp_Dialog::TypesList types;
417   selected( names, types, ids );
418   int nbSelected = names.size();
419
420   if ( myDlg->myMeshBtn->isOn() ) // mesh selected
421   {
422     myDlg->myMeshLine->setText("");
423     myMeshID = "";
424     if ( nbSelected == 1 ) {
425       myDlg->myMeshLine->setText( names.front() );
426       myMeshID = ids.front();
427     }
428     myDlg->myElemGeomList->clear();
429     myDlg->myElemGeomBtn->setEnabled( nbSelected == 1 );
430     myDlg->myNodeGeomList->clear();
431     myDlg->myNodeGeomBtn->setEnabled( nbSelected == 1 );
432     return;
433   }
434
435   // Filter off inappropriate shapes
436
437   QStringList goodNames, goodIds;
438   if (nbSelected > 0) {
439     // study
440     if (_PTR(Study) aStudy = SMESH::GetActiveStudyDocument()) {
441       // mesh
442       if (_PTR(SObject)  meshSO = aStudy->FindObjectID( myMeshID )) {
443         // shape to mesh
444         _PTR(SObject) anObj, shapeToMesh;
445         if (meshSO->FindSubObject(1, anObj) && anObj->ReferencedObject(shapeToMesh)) {
446           // loop on selected
447           QStringList::iterator name = names.begin(), id = ids.begin(), idEnd = ids.end();
448           for (; id != idEnd; ++id, ++name ) {
449             // shape SO
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 )
454                   shapeSO.reset();
455                 else
456                   shapeSO = shapeSO->GetFather();
457               if ( shapeSO ) {
458                 //printf( "selectionDone() %s %s\n", (*id).latin1(), (*name).latin1() );
459                 if ( !goodIds.contains( *id )) {
460                   goodIds.append( *id );
461                   goodNames.append( *name );
462                 }
463               }
464             }
465           }
466         }
467       }
468     }
469   }
470
471   if ( myDlg->myElemGeomBtn->isOn() ) // elem geomerty selection
472   {
473     myDlg->myElemGeomList->clear();
474     myDlg->myElemGeomList->insertStringList( goodNames );
475     myElemGeoIDs = goodIds;
476   }
477   else if ( myDlg->myNodeGeomBtn->isOn() ) // Node geomerty selection
478   {
479     myDlg->myNodeGeomList->clear();
480     myDlg->myNodeGeomList->insertStringList( goodNames );
481     myNodeGeoIDs = goodIds;
482   }
483
484   // enable/diable Apply, which can change at selection
485   myDlg->updateButtons();
486 }