Salome HOME
Merge from V6_3_BR 06/06/2011
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_Make2DFrom3DOp.cxx
1 // Copyright (C) 2007-2011  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.
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 // File   : SMESHGUI_Make2DFrom3D.cxx
20 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
21
22 #include "SMESHGUI_Make2DFrom3DOp.h"
23
24 #include "SMESHGUI.h"
25 #include "SMESHGUI_Utils.h"
26 #include "SMESHGUI_MeshUtils.h"
27 #include "SMESH_TypeFilter.hxx"
28 #include "SMESH_LogicalFilter.hxx"
29
30 // SALOME GUI includes
31 #include <LightApp_Application.h>
32 #include <LightApp_SelectionMgr.h>
33 #include <LightApp_UpdateFlags.h>
34 #include <SALOME_ListIO.hxx>
35 #include <SUIT_Desktop.h>
36 #include <SUIT_MessageBox.h>
37 #include <SUIT_OverrideCursor.h>
38 #include <SUIT_Session.h>
39 #include <SVTK_ViewModel.h>
40 #include <SalomeApp_Study.h>
41 #include <SalomeApp_Tools.h>
42
43 // IDL includes
44 #include <SALOMEconfig.h>
45 #include CORBA_SERVER_HEADER(SMESH_Group)
46
47 // Qt includes
48 #include <QGroupBox>
49 #include <QRadioButton>
50 #include <QLineEdit>
51 #include <QCheckBox>
52 #include <QHBoxLayout>
53 #include <QGridLayout>
54 #include <QToolButton>
55
56 #define SPACING 6
57 #define MARGIN  11
58
59 /*!
60   \class SMESHGUI_Make2DFrom3DDlg
61   \brief Copy Mesh dialog box
62 */
63
64 SMESHGUI_Make2DFrom3DDlg::SMESHGUI_Make2DFrom3DDlg( QWidget* parent )
65   : SMESHGUI_Dialog( parent, false, true, OK | Apply | Close | Help )
66 {
67   // title
68   setWindowTitle( tr("CAPTION") );
69
70   // mode
71   QGroupBox* aModeGrp = new QGroupBox( tr( "MODE" ), mainFrame() );
72   QHBoxLayout* aModeGrpLayout = new QHBoxLayout( aModeGrp );
73   aModeGrpLayout->setMargin( MARGIN );
74   aModeGrpLayout->setSpacing( SPACING );
75   my2dFrom3dRB = new QRadioButton( tr( "2D_FROM_3D" ), aModeGrp );
76   my1dFrom2dRB = new QRadioButton( tr( "1D_FROM_2D" ), aModeGrp );
77   my1dFrom3dRB = new QRadioButton( tr( "1D_FROM_3D" ), aModeGrp );
78   aModeGrpLayout->addWidget( my2dFrom3dRB );
79   aModeGrpLayout->addWidget( my1dFrom2dRB );
80   aModeGrpLayout->addWidget( my1dFrom3dRB );
81
82   // Groups of mesh faces
83   setObjectPixmap( "SMESH", tr( "ICON_SELECT" ) );
84   createObject( tr( "Groups" ), mainFrame(), Groups );
85   setNameIndication( Groups, ListOfNames );
86   objectWg( Groups, Btn )->hide();
87
88   // target
89   QGroupBox* aTargetGrp = new QGroupBox( tr( "TARGET" ), mainFrame() );
90   QGridLayout* aTargetGrpLayout = new QGridLayout( aTargetGrp );
91   aTargetGrpLayout->setMargin( MARGIN );
92   aTargetGrpLayout->setSpacing( SPACING );
93   myThisMeshRB   = new QRadioButton( tr( "THIS_MESH" ), aTargetGrp );
94   myNewMeshRB    = new QRadioButton( tr( "NEW_MESH" ),  aTargetGrp );
95   myMeshName     = new QLineEdit( aTargetGrp );
96   myCopyCheck    = new QCheckBox( tr( "COPY_SRC" ),     aTargetGrp );
97   aTargetGrpLayout->addWidget( myThisMeshRB,    0, 0 );
98   aTargetGrpLayout->addWidget( myNewMeshRB,     1, 0 );
99   aTargetGrpLayout->addWidget( myMeshName,     1, 1 );
100   aTargetGrpLayout->addWidget( myCopyCheck,    2, 0 );
101   myGroupCheck = new QCheckBox( tr( "CREATE_GROUP" ), mainFrame() );
102   myGroupName  = new QLineEdit( mainFrame() );
103
104   // layout
105   QGridLayout* aDlgLay = new QGridLayout( mainFrame() );
106   aDlgLay->setMargin( 0 );
107   aDlgLay->setSpacing( SPACING );
108   aDlgLay->addWidget( aModeGrp,     0, 0, 1, 3 );
109   aDlgLay->addWidget( objectWg( Groups,  Label ),   1, 0 );
110   aDlgLay->addWidget( objectWg( Groups,  Control ), 1, 1 );
111   aDlgLay->addWidget( aTargetGrp,   2, 0, 1, 3 );
112   aDlgLay->addWidget( myGroupCheck, 3, 0 );
113   aDlgLay->addWidget( myGroupName,  3, 1, 1, 2 );
114
115   // connect signals  
116   connect( myThisMeshRB, SIGNAL( clicked() ), this, SLOT( onTargetChanged() ) );
117   connect( myNewMeshRB,  SIGNAL( clicked() ), this, SLOT( onTargetChanged() ) );
118   connect( myGroupCheck, SIGNAL( clicked() ), this, SLOT( onGroupChecked() ) );
119
120   // init dlg
121   my2dFrom3dRB->setChecked( true );
122   myThisMeshRB->setChecked( true );
123   onTargetChanged();
124   onGroupChecked();
125 }
126
127 SMESHGUI_Make2DFrom3DDlg::~SMESHGUI_Make2DFrom3DDlg()
128 {
129 }
130
131 SMESH::Bnd_Dimension SMESHGUI_Make2DFrom3DDlg::mode() const
132 {
133   if ( my2dFrom3dRB->isChecked() )
134     return SMESH::BND_2DFROM3D;
135   else if ( my1dFrom2dRB->isChecked() )
136     return SMESH::BND_1DFROM2D;
137   else
138     return SMESH::BND_1DFROM3D;
139 }
140
141 bool SMESHGUI_Make2DFrom3DDlg::needNewMesh() const
142 {
143   return myNewMeshRB->isChecked();
144 }
145
146 QString SMESHGUI_Make2DFrom3DDlg::getNewMeshName() const
147 {
148   return myMeshName->text().trimmed();
149 }
150
151 void SMESHGUI_Make2DFrom3DDlg::setNewMeshName( const QString& name )
152 {
153   myMeshName->setText( name );
154 }
155
156 bool SMESHGUI_Make2DFrom3DDlg::needGroup() const
157 {
158   return myGroupCheck->isChecked();
159 }
160
161 QString SMESHGUI_Make2DFrom3DDlg::getGroupName() const
162 {
163   return myGroupName->text().trimmed();
164 }
165
166 void SMESHGUI_Make2DFrom3DDlg::setGroupName( const QString& name )
167 {
168   myGroupName->setText( name );
169 }
170
171 bool SMESHGUI_Make2DFrom3DDlg::copySource() const
172 {
173   return myCopyCheck->isChecked();
174 }
175
176 void SMESHGUI_Make2DFrom3DDlg::onTargetChanged()
177 {
178   myMeshName->setEnabled( myNewMeshRB->isChecked() );
179   myCopyCheck->setEnabled( myNewMeshRB->isChecked() );
180 }
181
182 void SMESHGUI_Make2DFrom3DDlg::onGroupChecked()
183 {
184   myGroupName->setEnabled( myGroupCheck->isChecked() );
185 }
186
187 /*!
188   \class SMESHGUI_Make2DFrom3DOp
189   \brief Copy Mesh operation class
190 */
191
192 SMESHGUI_Make2DFrom3DOp::SMESHGUI_Make2DFrom3DOp()
193  : SMESHGUI_SelectionOp()
194 {
195 }
196
197 SMESHGUI_Make2DFrom3DOp::~SMESHGUI_Make2DFrom3DOp()
198 {
199   if ( myDlg )
200     delete myDlg;
201 }
202
203 LightApp_Dialog* SMESHGUI_Make2DFrom3DOp::dlg() const
204 {
205   return myDlg;
206 }
207
208 void SMESHGUI_Make2DFrom3DOp::startOperation()
209 {
210   if( !myDlg )
211     myDlg = new SMESHGUI_Make2DFrom3DDlg( desktop() );
212
213   myHelpFileName = "make_2dmesh_from_3d_page.html";
214
215   SMESHGUI_SelectionOp::startOperation();
216
217   myDlg->setNewMeshName( SMESH::UniqueName( "Mesh_1" ) );
218   myDlg->setGroupName( SMESH::UniqueName( "Group" ) );
219   myDlg->show();
220
221   connect( myDlg->my2dFrom3dRB, SIGNAL( toggled(bool) ), this, SLOT( onModeChanged() ) );
222   connect( myDlg->my1dFrom2dRB, SIGNAL( toggled(bool) ), this, SLOT( onModeChanged() ) );
223   connect( myDlg->my1dFrom3dRB, SIGNAL( toggled(bool) ), this, SLOT( onModeChanged() ) );
224
225   onModeChanged();
226 }
227
228 void SMESHGUI_Make2DFrom3DOp::onModeChanged()
229 {
230   QRadioButton* b = dynamic_cast<QRadioButton*>( sender());
231   if ( b && !b->isChecked() )
232     return;
233
234   // enable "2D groups" field
235   bool enableGroups = ( myDlg->mode() == SMESH::BND_1DFROM3D );
236   myDlg->setObjectEnabled( SMESHGUI_Make2DFrom3DDlg::Groups, enableGroups );
237   ((QToolButton*) myDlg->objectWg( SMESHGUI_Make2DFrom3DDlg::Groups,
238                                    SMESHGUI_Make2DFrom3DDlg::Btn ))->setChecked( enableGroups );
239   
240   // install filter
241   int id =  enableGroups ? SMESHGUI_Make2DFrom3DDlg::Groups : SMESHGUI_Make2DFrom3DDlg::Mesh;
242   onDeactivateObject( id );
243   onActivateObject( id );
244 }
245
246 void SMESHGUI_Make2DFrom3DOp::selectionDone()
247 {
248   mySrcMesh = SMESH::SMESH_Mesh::_nil();
249   myDlg->clearSelection( SMESHGUI_Make2DFrom3DDlg::Groups );
250
251   if ( !dlg() ) return;
252
253   
254   if ( dlg()->isVisible() ) {
255     try {
256       QStringList names, ids;
257       LightApp_Dialog::TypesList types;
258       selected( names, types, ids );
259       myDlg->selectObject( names, types, ids );
260
261       SALOME_ListIO sel; selectionMgr()->selectedObjects( sel, SVTK_Viewer::Type() );
262       if ( !sel.IsEmpty() )
263       {
264         SMESH::SMESH_IDSource_var IS = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(sel.First());
265         if(!CORBA::is_nil(IS))
266           mySrcMesh = IS->GetMesh();
267       }
268     }
269     catch ( const SALOME::SALOME_Exception& S_ex ) {
270       SalomeApp_Tools::QtCatchCorbaException( S_ex );
271     }
272     catch ( ... ) {
273     }
274   }
275 }
276
277 SUIT_SelectionFilter* SMESHGUI_Make2DFrom3DOp::createFilter( const int theId ) const
278 {
279   MeshObjectType type = ( theId == SMESHGUI_Make2DFrom3DDlg::Groups ? GROUP_FACE : MESH );
280   SUIT_SelectionFilter* f = new SMESH_TypeFilter( type );
281   return f;
282 }
283
284 bool SMESHGUI_Make2DFrom3DOp::isValid( QString& msg ) const
285 {
286   if ( !dlg() ) return false;
287
288   // check if a mesh is selected
289   if ( mySrcMesh->_is_nil() )
290   {
291     msg = tr( "SMESH_ERR_NO_INPUT_MESH" );
292     return false;
293   }
294   // check if groups are selected
295   SMESH::Bnd_Dimension mode = myDlg->mode();
296   if ( mode == SMESH::BND_1DFROM3D )
297   {
298     SMESH::SMESH_GroupBase_var grp;
299     QStringList entries;
300     dlg()->selectedObject( SMESHGUI_Make2DFrom3DDlg::Groups, entries );
301     if ( !entries.isEmpty() )
302     {
303       _PTR(SObject) sobj = SMESHGUI::activeStudy()->studyDS()->FindObjectID( entries[0].toLatin1().constData() );
304       if ( sobj )
305         grp = SMESH::SObjectToInterface<SMESH::SMESH_GroupBase>( sobj );
306     }
307     if ( grp->_is_nil() ) {
308       msg = tr( "SMESH_ERR_NO_INPUT_GROUP" );
309       return false;
310     }
311   }
312   else
313   {
314     // check if mesh contains elements of required type
315     SMESH::Bnd_Dimension mode = myDlg->mode();
316
317     if ( mode == SMESH::BND_2DFROM3D && mySrcMesh->NbVolumes() == 0 ) {
318       msg = tr( "SMESH_ERR_NO_3D_ELEMENTS" );
319       return false;
320     }
321     else if ( mode == SMESH::BND_1DFROM2D && mySrcMesh->NbFaces() == 0  ) {
322       msg = tr( "SMESH_ERR_NO_2D_ELEMENTS" );
323       return false;
324     }
325   }
326
327   // check if new mesh name is specified
328   if ( myDlg->needNewMesh() && myDlg->getNewMeshName().isEmpty() ) {
329     msg = tr( "SMESH_ERR_MESH_NAME_NOT_SPECIFIED" );
330     return false;
331   }
332
333   // check if group name is specified
334   if ( myDlg->needGroup() && myDlg->getGroupName().isEmpty() ) {
335     msg = tr( "SMESH_ERR_GRP_NAME_NOT_SPECIFIED" );
336     return false;
337   }
338     
339   return true;
340 }
341
342 bool SMESHGUI_Make2DFrom3DOp::compute2DMesh( QStringList& theEntryList )
343 {
344   SUIT_OverrideCursor wc;
345
346   bool ok = false;
347   try {
348     QStringList entries;
349     dlg()->selectedObject( SMESHGUI_Make2DFrom3DDlg::Groups, entries );
350     SMESH::ListOfIDSources_var groups = new SMESH::ListOfIDSources;
351     groups->length( entries.count() );
352     for ( int i = 0; i < entries.count(); ++i )
353     {
354       _PTR(SObject) sobj = SMESHGUI::activeStudy()->studyDS()->FindObjectID( entries[i].toLatin1().constData() );
355       SMESH::SMESH_IDSource_var grp = SMESH::SObjectToInterface<SMESH::SMESH_IDSource>( sobj );  
356       groups[i] = grp;
357     }
358     SMESH::Bnd_Dimension mode = myDlg->mode();
359     QString meshName  = myDlg->needNewMesh() ? myDlg->getNewMeshName() : QString();
360     QString groupName = myDlg->needGroup()   ? myDlg->getGroupName()   : QString();
361     bool copyAll = myDlg->copySource();
362
363     if ( !CORBA::is_nil( mySrcMesh ) ) {
364       SMESH::SMESH_MeshEditor_var aMeshEditor = mySrcMesh->GetMeshEditor();
365       SMESH::SMESH_Group_var newGrp;
366       SMESH::SMESH_Mesh_var newMesh;
367       CORBA::Long nbAdded = aMeshEditor->MakeBoundaryElements( mode,
368                                                                groupName.toLatin1().constData(),
369                                                                meshName.toLatin1().constData(),
370                                                                copyAll,
371                                                                groups,
372                                                                newMesh.out(),
373                                                                newGrp.out() );
374       SUIT_MessageBox::information( myDlg,
375                                     tr("SMESH_INFORMATION"),
376                                     tr("NB_ADDED").arg( nbAdded ));
377       if ( !newMesh->_is_nil() ) {
378         if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( newMesh ) )
379           theEntryList.append( aSObject->GetID().c_str() );
380 #ifdef WITHGENERICOBJ
381         newMesh->UnRegister();
382 #endif
383       }
384       if ( !newGrp->_is_nil() ) {
385 #ifdef WITHGENERICOBJ
386         newGrp->UnRegister();
387 #endif
388       }
389       ok = true;
390     }
391   }
392   catch ( ... ) {
393   }
394   return ok;
395 }
396
397 bool SMESHGUI_Make2DFrom3DOp::onApply()
398 {
399   if ( isStudyLocked() )
400     return false;
401
402   QString msg;
403   if ( !isValid( msg ) ) {
404     dlg()->show();
405     if ( msg != "" )
406       SUIT_MessageBox::warning( myDlg, tr( "SMESH_ERROR" ), msg );
407     return false;
408   }
409
410   QStringList anEntryList;
411   bool res = false;
412   try {
413     res = compute2DMesh( anEntryList );
414   }
415   catch ( const SALOME::SALOME_Exception& S_ex ) {
416     SalomeApp_Tools::QtCatchCorbaException( S_ex );
417   }
418   catch ( ... ) {
419   }
420
421   if ( res ) {
422     SMESHGUI::Modified();
423     update( UF_ObjBrowser | UF_Model );
424     if( LightApp_Application* anApp =
425         dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
426       anApp->browseObjects( anEntryList, isApplyAndClose() );
427     myDlg->setNewMeshName( SMESH::UniqueName( "Mesh_1" ) );
428     myDlg->setGroupName( SMESH::UniqueName( "Group" ) );
429   }
430   else {
431     SUIT_MessageBox::warning( myDlg, tr( "SMESH_ERROR" ), tr( "SMESH_OPERATION_FAILED" ) );
432   }
433
434   return res;
435 }