Salome HOME
4ffc3f09e4d30b02b8d701cd048eca79b95b0e7a
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_Make2DFrom3DOp.cxx
1 //  Copyright (C) 2007-2010  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_UpdateFlags.h>
32 #include <SalomeApp_Tools.h>
33 #include <SalomeApp_Study.h>
34 #include <SUIT_Desktop.h>
35 #include <SUIT_MessageBox.h>
36 #include <SUIT_OverrideCursor.h>
37
38 // IDL includes
39 #include <SALOMEconfig.h>
40 #include CORBA_SERVER_HEADER(SMESH_Group)
41
42 // Qt includes
43 #include <QGroupBox>
44 #include <QRadioButton>
45 #include <QLineEdit>
46 #include <QCheckBox>
47 #include <QHBoxLayout>
48 #include <QGridLayout>
49
50 #define SPACING 6
51 #define MARGIN  11
52
53 /*!
54   \class SMESHGUI_Make2DFrom3DDlg
55   \brief Copy Mesh dialog box
56 */
57
58 SMESHGUI_Make2DFrom3DDlg::SMESHGUI_Make2DFrom3DDlg( QWidget* parent )
59  : SMESHGUI_Dialog( parent, false, true, OK | Apply | Close | Help )
60 {
61   // title
62   setWindowTitle( tr("CAPTION") );
63
64   // mesh
65   setObjectPixmap( "SMESH", tr( "ICON_SELECT" ) );
66   createObject( tr( "MESH" ), mainFrame(), Mesh );
67
68   // mode
69   QGroupBox* aModeGrp = new QGroupBox( tr( "MODE" ), mainFrame() );
70   QHBoxLayout* aModeGrpLayout = new QHBoxLayout( aModeGrp );
71   aModeGrpLayout->setMargin( MARGIN );
72   aModeGrpLayout->setSpacing( SPACING );
73   my2dFrom3dRB = new QRadioButton( tr( "2D_FROM_3D" ), aModeGrp );
74   my1dFrom2dRB = new QRadioButton( tr( "1D_FROM_2D" ), aModeGrp );
75   my1dFrom3dRB = new QRadioButton( tr( "1D_FROM_3D" ), aModeGrp );
76   aModeGrpLayout->addWidget( my2dFrom3dRB );
77   aModeGrpLayout->addWidget( my1dFrom2dRB );
78   aModeGrpLayout->addWidget( my1dFrom3dRB );
79
80   // target
81   QGroupBox* aTargetGrp = new QGroupBox( tr( "TARGET" ), mainFrame() );
82   QGridLayout* aTargetGrpLayout = new QGridLayout( aTargetGrp );
83   aTargetGrpLayout->setMargin( MARGIN );
84   aTargetGrpLayout->setSpacing( SPACING );
85   myThisMeshRB   = new QRadioButton( tr( "THIS_MESH" ), aTargetGrp );
86   myNewMeshRB    = new QRadioButton( tr( "NEW_MESH" ),  aTargetGrp );
87   myMeshName     = new QLineEdit( aTargetGrp );
88   myCopyCheck    = new QCheckBox( tr( "COPY_SRC" ),     aTargetGrp );
89   myMissingCheck = new QCheckBox( tr( "MISSING_ONLY" ), aTargetGrp );
90   aTargetGrpLayout->addWidget( myThisMeshRB,    0, 0 );
91   aTargetGrpLayout->addWidget( myNewMeshRB,     1, 0 );
92   aTargetGrpLayout->addWidget( myMeshName,     1, 1 );
93   aTargetGrpLayout->addWidget( myCopyCheck,    2, 0 );
94   aTargetGrpLayout->addWidget( myMissingCheck, 2, 1 );
95   myGroupCheck = new QCheckBox( tr( "CREATE_GROUP" ), mainFrame() );
96   myGroupName  = new QLineEdit( mainFrame() );
97
98   // layout
99   QGridLayout* aDlgLay = new QGridLayout( mainFrame() );
100   aDlgLay->setMargin( 0 );
101   aDlgLay->setSpacing( SPACING );
102   aDlgLay->addWidget( objectWg( Mesh,  Label ),   0, 0 );
103   aDlgLay->addWidget( objectWg( Mesh,  Btn ),     0, 1 );
104   aDlgLay->addWidget( objectWg( Mesh,  Control ), 0, 2 );
105   aDlgLay->addWidget( aModeGrp,     1, 0, 1, 3 );
106   aDlgLay->addWidget( aTargetGrp,   2, 0, 1, 3 );
107   aDlgLay->addWidget( myGroupCheck, 3, 0 );
108   aDlgLay->addWidget( myGroupName,  3, 1, 1, 2 );
109
110   // connect signals  
111   connect( myThisMeshRB, SIGNAL( clicked() ), this, SLOT( onTargetChanged() ) );
112   connect( myNewMeshRB,  SIGNAL( clicked() ), this, SLOT( onTargetChanged() ) );
113   connect( myGroupCheck, SIGNAL( clicked() ), this, SLOT( onGroupChecked() ) );
114
115   // init dlg
116   my2dFrom3dRB->setChecked( true );
117   myThisMeshRB->setChecked( true );
118   myMissingCheck->setChecked( true );
119   onTargetChanged();
120   onGroupChecked();
121 }
122
123 SMESHGUI_Make2DFrom3DDlg::~SMESHGUI_Make2DFrom3DDlg()
124 {
125 }
126
127 SMESH::Bnd_Dimension SMESHGUI_Make2DFrom3DDlg::mode() const
128 {
129   if ( my2dFrom3dRB->isChecked() )
130     return SMESH::BND_2DFROM3D;
131   else if ( my1dFrom2dRB->isChecked() )
132     return SMESH::BND_1DFROM2D;
133   else
134     return SMESH::BND_1DFROM3D;
135 }
136
137 bool SMESHGUI_Make2DFrom3DDlg::needNewMesh() const
138 {
139   return myNewMeshRB->isChecked();
140 }
141
142 QString SMESHGUI_Make2DFrom3DDlg::getNewMeshName() const
143 {
144   return myMeshName->text().trimmed();
145 }
146
147 void SMESHGUI_Make2DFrom3DDlg::setNewMeshName( const QString& name )
148 {
149   myMeshName->setText( name );
150 }
151
152 bool SMESHGUI_Make2DFrom3DDlg::needGroup() const
153 {
154   return myGroupCheck->isChecked();
155 }
156
157 QString SMESHGUI_Make2DFrom3DDlg::getGroupName() const
158 {
159   return myGroupName->text().trimmed();
160 }
161
162 void SMESHGUI_Make2DFrom3DDlg::setGroupName( const QString& name )
163 {
164   myGroupName->setText( name );
165 }
166
167 bool SMESHGUI_Make2DFrom3DDlg::copySource() const
168 {
169   return myCopyCheck->isChecked();
170 }
171
172 bool SMESHGUI_Make2DFrom3DDlg::copyMissingOnly() const
173 {
174   return myMissingCheck->isChecked();
175 }
176
177 void SMESHGUI_Make2DFrom3DDlg::onTargetChanged()
178 {
179   myMeshName->setEnabled( myNewMeshRB->isChecked() );
180   myCopyCheck->setEnabled( myNewMeshRB->isChecked() );
181   myMissingCheck->setEnabled( myNewMeshRB->isChecked() );
182 }
183
184 void SMESHGUI_Make2DFrom3DDlg::onGroupChecked()
185 {
186   myGroupName->setEnabled( myGroupCheck->isChecked() );
187 }
188
189 /*!
190   \class SMESHGUI_Make2DFrom3DOp
191   \brief Copy Mesh operation class
192 */
193
194 SMESHGUI_Make2DFrom3DOp::SMESHGUI_Make2DFrom3DOp()
195  : SMESHGUI_SelectionOp()
196 {
197 }
198
199 SMESHGUI_Make2DFrom3DOp::~SMESHGUI_Make2DFrom3DOp()
200 {
201   if ( myDlg )
202     delete myDlg;
203 }
204
205 LightApp_Dialog* SMESHGUI_Make2DFrom3DOp::dlg() const
206 {
207   return myDlg;
208 }
209
210 void SMESHGUI_Make2DFrom3DOp::startOperation()
211 {
212   if( !myDlg )
213     myDlg = new SMESHGUI_Make2DFrom3DDlg( desktop() );
214
215   mySrc = SMESH::SMESH_IDSource::_nil();
216   
217   myHelpFileName = "make_2dmesh_from_3d_page.html";
218
219   SMESHGUI_SelectionOp::startOperation();
220
221   myDlg->activateObject( SMESHGUI_Make2DFrom3DDlg::Mesh );
222   myDlg->setNewMeshName( SMESH::UniqueName( "Mesh_1" ) );
223   myDlg->setGroupName( SMESH::UniqueName( "Group" ) );
224   myDlg->show();
225
226   selectionDone();
227 }
228
229 void SMESHGUI_Make2DFrom3DOp::selectionDone()
230 {
231   if ( !dlg() ) return;
232
233   if ( dlg()->isVisible() ) {
234     try {
235       QStringList names, ids;
236       LightApp_Dialog::TypesList types;
237       selected( names, types, ids );
238       if ( names.count() == 1 )
239         myDlg->selectObject( names, types, ids );
240       else
241         myDlg->clearSelection();
242     }
243     catch ( const SALOME::SALOME_Exception& S_ex ) {
244       SalomeApp_Tools::QtCatchCorbaException( S_ex );
245     }
246     catch ( ... ) {
247     }
248   }
249 }
250
251 SUIT_SelectionFilter* SMESHGUI_Make2DFrom3DOp::createFilter( const int theId ) const
252 {
253   SUIT_SelectionFilter* f = 0;
254   if ( theId == SMESHGUI_Make2DFrom3DDlg::Mesh ) {
255     QList<SUIT_SelectionFilter*> filters;
256     filters.append( new SMESH_TypeFilter( MESHorSUBMESH ) );
257     filters.append( new SMESH_TypeFilter( GROUP ) );
258     f = new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR );
259   }
260   return f;
261 }
262
263 bool SMESHGUI_Make2DFrom3DOp::isValid( QString& msg ) const
264 {
265   if ( !dlg() ) return false;
266
267   // check if any source data is selected
268   QString entry = myDlg->selectedObject( SMESHGUI_Make2DFrom3DDlg::Mesh );
269   SMESH::SMESH_IDSource_var obj;
270   _PTR(SObject) sobj = SMESHGUI::activeStudy()->studyDS()->FindObjectID( entry.toLatin1().constData() );
271   if ( sobj )
272     obj = SMESH::SObjectToInterface<SMESH::SMESH_IDSource>( sobj );  
273
274   if ( obj->_is_nil() ) {
275     msg = tr( "SMESH_ERR_NO_INPUT_MESH" );
276     return false;
277   }
278
279   // check if source contains elements of required type
280   SMESH::Bnd_Dimension mode = myDlg->mode();
281   SMESH::array_of_ElementType_var types = obj->GetTypes();
282   
283   bool has3d = false;
284   bool has2d = false;
285   for ( int i = 0; i < types->length(); i++ ) {
286     if      ( types[i] == SMESH::VOLUME ) has3d = true;
287     else if ( types[i] == SMESH::FACE )   has2d = true;
288   }
289
290   if ( ( mode == SMESH::BND_2DFROM3D || mode == SMESH::BND_1DFROM3D ) && !has3d ) {
291     msg = tr( "SMESH_ERR_NO_3D_ELEMENTS" );
292     return false;
293   }
294   else if ( mode == SMESH::BND_1DFROM2D && !has2d ) {
295     msg = tr( "SMESH_ERR_NO_2D_ELEMENTS" );
296     return false;
297   }
298
299   // check if new mesh name is specified
300   if ( myDlg->needNewMesh() && myDlg->getNewMeshName().isEmpty() ) {
301     msg = tr( "SMESH_ERR_MESH_NAME_NOT_SPECIFIED" );
302     return false;
303   }
304
305   // check if group name is specified
306   if ( myDlg->needGroup() && myDlg->getGroupName().isEmpty() ) {
307     msg = tr( "SMESH_ERR_GRP_NAME_NOT_SPECIFIED" );
308     return false;
309   }
310     
311   return true;
312 }
313
314 bool SMESHGUI_Make2DFrom3DOp::compute2DMesh()
315 {
316   SUIT_OverrideCursor wc;
317
318   bool ok = false;
319   try {
320     QString entry = myDlg->selectedObject( SMESHGUI_Make2DFrom3DDlg::Mesh );
321     _PTR(SObject) sobj = SMESHGUI::activeStudy()->studyDS()->FindObjectID( entry.toLatin1().constData() );
322     SMESH::SMESH_IDSource_var obj = SMESH::SObjectToInterface<SMESH::SMESH_IDSource>( sobj );  
323     
324     SMESH::Bnd_Dimension mode = myDlg->mode();
325     QString meshName  = myDlg->needNewMesh() ? myDlg->getNewMeshName() : QString();
326     QString groupName = myDlg->needGroup()   ? myDlg->getGroupName()   : QString();
327     bool copySrc = myDlg->copySource();
328     bool copyAll = !myDlg->copyMissingOnly();
329
330     SMESH::SMESH_Mesh_var srcMesh = SMESH::SMESH_Mesh::_narrow( obj );
331     if ( CORBA::is_nil( srcMesh ) ) {
332       SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_narrow( obj );
333       if ( !CORBA::is_nil( subMesh ) )
334         srcMesh = subMesh->GetFather();
335     }
336     if ( CORBA::is_nil( srcMesh ) ) {
337       SMESH::SMESH_GroupBase_var grp = SMESH::SMESH_GroupBase::_narrow( obj );
338       if ( !CORBA::is_nil( grp ) )
339         srcMesh = grp->GetMesh();
340     }
341
342     if ( !CORBA::is_nil( srcMesh ) ) {
343       SMESH::SMESH_MeshEditor_var aMeshEditor = srcMesh->GetMeshEditor();
344       SMESH::SMESH_Group_var newGrp;
345       SMESH::SMESH_Mesh_var mesh = aMeshEditor->MakeBoundaryMesh( obj.in(), 
346                                                                   mode,
347                                                                   groupName.toLatin1().constData(),
348                                                                   meshName.toLatin1().constData(),
349                                                                   copySrc,
350                                                                   copyAll,
351                                                                   newGrp.out() );
352       if ( !mesh->_is_nil() ) {
353 #ifdef WITHGENERICOBJ
354         mesh->Destroy();
355 #endif
356       }
357       if ( !newGrp->_is_nil() ) {
358 #ifdef WITHGENERICOBJ
359         newGrp->Destroy();
360 #endif
361       }
362       ok = true;
363     }
364   }
365   catch ( ... ) {
366   }
367   return ok;
368 }
369
370 bool SMESHGUI_Make2DFrom3DOp::onApply()
371 {
372   if ( isStudyLocked() )
373     return false;
374
375   QString msg;
376   if ( !isValid( msg ) ) {
377     dlg()->show();
378     if ( msg != "" )
379       SUIT_MessageBox::warning( myDlg, tr( "SMESH_ERROR" ), msg );
380     return false;
381   }
382
383   bool res = false;
384   try {
385     res = compute2DMesh();
386   }
387   catch ( const SALOME::SALOME_Exception& S_ex ) {
388     SalomeApp_Tools::QtCatchCorbaException( S_ex );
389   }
390   catch ( ... ) {
391   }
392
393   if ( res ) {
394     SMESHGUI::Modified();
395     update( UF_ObjBrowser | UF_Model );
396     myDlg->setNewMeshName( SMESH::UniqueName( "Mesh_1" ) );
397     myDlg->setGroupName( SMESH::UniqueName( "Group" ) );
398   }
399   else {
400     SUIT_MessageBox::warning( myDlg, tr( "SMESH_ERROR" ), tr( "SMESH_OPERATION_FAILED" ) );
401   }
402
403   return res;
404 }