Salome HOME
Working version of dual_meshing (using medcoupling) functionality
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_CreateDualMeshOp.cxx
1 // Copyright (C) 2007-2021  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, or (at your option) any later version.
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
23 // SMESH SMESHGUI : GUI for SMESH component
24 // File   : SMESHGUI_CreateDualMeshOp.cxx
25 // Author : Yoann AUDOUIN (EDF)
26 // SMESH includes
27 //
28 #include "SMESHGUI_CreateDualMeshOp.h"
29
30 #include "SMESHGUI.h"
31 #include "SMESHGUI_CreateDualMeshDlg.h"
32 #include "SMESHGUI_MeshEditPreview.h"
33 #include "SMESHGUI_Utils.h"
34 #include "SMESH_ActorUtils.h"
35 #include "SMESH_TypeFilter.hxx"
36 #include "SMDSAbs_ElementType.hxx"
37
38 // SALOME GUI includes
39 #include <LightApp_UpdateFlags.h>
40 #include <SUIT_MessageBox.h>
41 #include <SUIT_OverrideCursor.h>
42 #include <SalomeApp_Tools.h>
43 #include <SalomeApp_Application.h>
44 #include <SALOME_Actor.h>
45
46 // Qt includes
47 #include <QLineEdit>
48
49 // IDL includes
50 #include <SALOMEconfig.h>
51 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
52
53 // VTK includes
54 #include <vtkProperty.h>
55
56 //================================================================================
57 /*!
58  * \brief Constructor
59  *
60  * Initialize operation
61 */
62 //================================================================================
63 SMESHGUI_CreateDualMeshOp::SMESHGUI_CreateDualMeshOp()
64   : SMESHGUI_SelectionOp(),
65     myDlg( 0 )
66 {
67 }
68
69 //================================================================================
70 /*!
71  * \brief Destructor
72 */
73 //================================================================================
74 SMESHGUI_CreateDualMeshOp::~SMESHGUI_CreateDualMeshOp()
75 {
76   if ( myDlg ) delete myDlg;
77 }
78
79 //================================================================================
80 /*!
81  * \brief Gets dialog of this operation
82   * \retval LightApp_Dialog* - pointer to dialog of this operation
83 */
84 //================================================================================
85 LightApp_Dialog* SMESHGUI_CreateDualMeshOp::dlg() const
86 {
87   return myDlg;
88 }
89
90 //================================================================================
91 /*!
92  * \brief Creates dialog if necessary and shows it
93  *
94  * Virtual method redefined from base class called when operation is started creates
95  * dialog if necessary and shows it, activates selection
96  */
97 //================================================================================
98 void SMESHGUI_CreateDualMeshOp::startOperation()
99 {
100   if( !myDlg )
101   {
102     myDlg = new SMESHGUI_CreateDualMeshDlg( );
103   }
104   connect( myDlg, SIGNAL( onClicked( int ) ), SLOT( ConnectRadioButtons( int ) ) );
105
106   myHelpFileName = "create_dual_mesh.html";
107
108   SMESHGUI_SelectionOp::startOperation();
109
110   myDlg->activateObject( 0 );
111   myDlg->ShowWarning( false );
112   myDlg->show();
113
114   selectionDone();
115 }
116
117 //================================================================================
118 /*!
119  * \brief Updates dialog's look and feel
120  *
121  * Virtual method redefined from the base class updates dialog's look and feel
122  */
123 //================================================================================
124 void SMESHGUI_CreateDualMeshOp::selectionDone()
125 {
126   if ( !dlg()->isVisible() )
127     return;
128
129   SMESHGUI_SelectionOp::selectionDone();
130   try
131   {
132     QString anObjEntry = myDlg->selectedObject( 0 );
133     _PTR(SObject) pObj = SMESH::getStudy()->FindObjectID( anObjEntry.toUtf8().data() );
134     if ( !pObj ) return;
135
136     SMESH::SMESH_IDSource_var idSource =
137       SMESH::SObjectToInterface<SMESH::SMESH_IDSource>( pObj );
138
139     myDlg->setButtonEnabled( true, QtxDialog::OK | QtxDialog::Apply );
140     if( idSource->_is_nil() )
141     {
142       myDlg->setButtonEnabled( false, QtxDialog::OK | QtxDialog::Apply );
143       return;
144     }
145     SMESH::SMESH_Mesh_var      mesh = idSource->GetMesh();
146
147     // show warning on non-conformal result mesh
148     if ( ! idSource->_is_nil() )
149     {
150       SMESH::SMESH_subMesh_var subMesh =
151         SMESH::SObjectToInterface<SMESH::SMESH_subMesh>( pObj );
152       // TODO: Check that mesh is only tetra
153       if (!checkMesh(idSource)){
154         myDlg->ShowWarning( true );
155       }
156     }
157     std::string mesh_name = "dual_" + pObj->GetName();
158     myDlg->myMeshName->setText(QString(mesh_name.c_str()));
159
160   }
161   catch ( const SALOME::SALOME_Exception& S_ex )
162   {
163     SalomeApp_Tools::QtCatchCorbaException( S_ex );
164   }
165   catch ( ... )
166   {
167   }
168
169 }
170
171 //================================================================================
172 /*!
173  * \brief Creates selection filter
174   * \param theId - identifier of current selection widget
175   * \retval SUIT_SelectionFilter* - pointer to the created filter or null
176  *
177  * Creates selection filter in accordance with identifier of current selection widget
178  */
179 //================================================================================
180 SUIT_SelectionFilter* SMESHGUI_CreateDualMeshOp::createFilter( const int theId ) const
181 {
182   if ( theId == 0 )
183     return new SMESH_TypeFilter( SMESH::MESHorSUBMESH );
184   else
185     return 0;
186 }
187
188 //================================================================================
189 /*!
190  * \brief Edits mesh
191  *
192  * Virtual slot redefined from the base class called when "Apply" button is clicked
193  */
194 //================================================================================
195 bool SMESHGUI_CreateDualMeshOp::onApply()
196 {
197   SUIT_OverrideCursor aWaitCursor;
198
199   QString aMess;
200   QStringList anEntryList;
201
202   QString anObjEntry = myDlg->selectedObject( 0 );
203   _PTR(SObject) pObj = SMESH::getStudy()->FindObjectID( anObjEntry.toUtf8().data() );
204   if ( !pObj )
205   {
206     dlg()->show();
207     SUIT_MessageBox::warning( myDlg,
208                               tr( "SMESH_WRN_WARNING" ), tr("MESH_IS_NOT_SELECTED") );
209     return false;
210   }
211
212   SMESH::SMESH_Mesh_var mesh;
213   SMESH::SMESH_IDSource_var idSource =
214     SMESH::SObjectToInterface<SMESH::SMESH_IDSource>( pObj );
215   if( !CORBA::is_nil(idSource) )
216     mesh = idSource->GetMesh();
217
218   if( CORBA::is_nil(mesh) )
219   {
220     SUIT_MessageBox::warning( myDlg,
221                               tr( "SMESH_WRN_WARNING" ), tr("REF_IS_NULL") );
222     return false;
223   }
224
225   bool aResult = false;
226   SMESH::SMESH_Gen_var gen = SMESHGUI::GetSMESHGen();
227   SMESH::SMESH_Mesh_var newMesh;
228   QByteArray newMeshName=myDlg->myMeshName->text().toUtf8();
229   try
230   {
231     // TODO: change name as previous name + "_dual"
232     newMesh = gen->CreateDualMesh(mesh, newMeshName.constData());
233
234     if ( !newMesh->_is_nil() )
235       if ( _PTR(SObject) aSObject = SMESH::ObjectToSObject( newMesh ) )
236       {
237         anEntryList.append( aSObject->GetID().c_str() );
238
239         SMESH::SetName( aSObject, newMeshName );
240       }
241     aResult = true;
242   }
243   catch ( const SALOME::SALOME_Exception& S_ex )
244   {
245     SalomeApp_Tools::QtCatchCorbaException( S_ex );
246     aResult = false;
247   }
248   catch ( ... )
249   {
250     aResult = false;
251   }
252   if( aResult )
253   {
254     SMESHGUI::Modified();
255     selectionDone();
256     update( UF_ObjBrowser | UF_Model | UF_Viewer );
257
258   }
259   SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
260
261   // updateObjBrowser(true);
262   // SMESHGUI::Modified();
263
264   // if( LightApp_Application* anApp =
265   //     dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
266   //   anApp->browseObjects( anEntryList, true );
267
268   return true;
269
270 }
271
272 //================================================================================
273 /*! checkMesh
274  *  Verify that mesh as only tetraheadrons as 3D elements
275  */
276 //================================================================================
277
278 bool
279 SMESHGUI_CreateDualMeshOp::checkMesh( const SMESH::SMESH_IDSource_var& idSource)
280 {
281   SMESH::smIdType_array_var nbElemOfType = idSource->GetMeshInfo();
282   // Checking that the mesh only has Tetrahedron
283   bool hasOnlyTetra  = (
284                     nbElemOfType[SMDSEntity_Tetra     ] &&
285                    !nbElemOfType[SMDSEntity_Hexa      ] &&
286                    !nbElemOfType[SMDSEntity_Pyramid   ] &&
287                    !nbElemOfType[SMDSEntity_Polygon   ] &&
288                    !nbElemOfType[SMDSEntity_Penta     ] );
289
290   return hasOnlyTetra;
291 }