Salome HOME
b7209fa88778aa3b0734be5c707a2ccb649776d2
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_AddSubMeshOp.cxx
1 //  SMESH SMESHGUI : GUI for SMESH component
2 //
3 //  Copyright (C) 2003  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
21 //
22 //
23 //
24 //  File   : SMESHGUI_AddSubMeshOp.cxx
25 //  Author : Nicolas REJNERI
26 //  Module : SMESH
27 //  $Header$
28
29 #include "SMESHGUI_AddSubMeshOp.h"
30 #include <SMESHGUI_AddSubMeshDlg.h>
31 #include <SMESHGUI_GEOMGenUtils.h>
32 #include <SMESHGUI_HypothesesUtils.h>
33 #include <SMESHGUI_Utils.h>
34 #include <SMESHGUI.h>
35
36 #include <SMESH_NumberFilter.hxx>
37 #include <SMESH_TypeFilter.hxx>
38
39 #include <SUIT_SelectionFilter.h>
40 #include <SUIT_OverrideCursor.h>
41 #include <SUIT_MessageBox.h>
42
43 #include <SalomeApp_SelectionMgr.h>
44 #include <SalomeApp_UpdateFlags.h>
45 #include <SalomeApp_Tools.h>
46
47 #include <TColStd_MapOfInteger.hxx>
48
49 #include <SALOMEDS_SObject.hxx>
50
51 #include <utilities.h>
52
53 //=================================================================================
54 // function : Constructor
55 // purpose  :
56 //=================================================================================
57 SMESHGUI_AddSubMeshOp::SMESHGUI_AddSubMeshOp()
58 : SMESHGUI_SelectionOp(),
59   myDlg( 0 )
60 {
61   setAutoResumed( true );
62 }
63
64 //=================================================================================
65 // function : Destructor
66 // purpose  :
67 //=================================================================================
68 SMESHGUI_AddSubMeshOp::~SMESHGUI_AddSubMeshOp()
69 {
70   if( myDlg )
71     delete myDlg;
72 }
73
74 //=================================================================================
75 // function : startOperation
76 // purpose  :
77 //=================================================================================
78 void SMESHGUI_AddSubMeshOp::startOperation()
79 {
80   if( !myDlg )
81   {
82     myDlg = new SMESHGUI_AddSubMeshDlg();
83     connect( myDlg, SIGNAL( nameChanged( const QString& ) ), this, SLOT( onNameChanged( const QString& ) ) );
84   }
85
86   SMESHGUI_SelectionOp::startOperation();
87
88   myDlg->show();
89 }
90
91 //=================================================================================
92 // function : dlg
93 // purpose  :
94 //=================================================================================
95 SalomeApp_Dialog* SMESHGUI_AddSubMeshOp::dlg() const
96 {
97   return myDlg;
98 }
99
100 //=================================================================================
101 // function : selectionDone
102 // purpose  :
103 //=================================================================================
104 void SMESHGUI_AddSubMeshOp::selectionDone()
105 {
106   SMESHGUI_SelectionOp::selectionDone();
107   if( myDlg )
108     updateDialog();
109 }
110
111 //=================================================================================
112 // function : createFilter
113 // purpose  :
114 //=================================================================================
115 SUIT_SelectionFilter* SMESHGUI_AddSubMeshOp::createFilter( const int id ) const
116 {
117   if( id==SMESHGUI_AddSubMeshDlg::GeomObj )
118   {
119     TColStd_MapOfInteger allTypesMap;
120     for (int i = 0; i < 10; i++)
121       allTypesMap.Add(i);
122     return new SMESH_NumberFilter ("GEOM", TopAbs_SHAPE, 0, allTypesMap);
123   }
124
125   if( id==SMESHGUI_AddSubMeshDlg::MeshObj )
126     return new SMESH_TypeFilter (MESH);
127
128   else if( id==SMESHGUI_AddSubMeshDlg::Algo )
129     return new SMESH_TypeFilter (ALGORITHM);
130
131   else if( id==SMESHGUI_AddSubMeshDlg::Hypo )
132     return new SMESH_TypeFilter (HYPOTHESIS);
133
134   else
135     return 0;
136 }
137
138 //=================================================================================
139 // function : commitOperation
140 // purpose  :
141 //=================================================================================
142 bool SMESHGUI_AddSubMeshOp::onApply()
143 {
144   if( isStudyLocked() )
145     return false;
146
147   QString myNameSubMesh = myDlg->subMeshName();
148   if (myNameSubMesh.isEmpty())
149   {
150     SUIT_MessageBox::warn1( dlg(), tr("SMESH_WRN_WARNING"),
151                             tr("SMESH_WRN_EMPTY_NAME"), tr("SMESH_BUT_OK"));
152     return false;
153   }
154
155   QStringList selMesh, selGeom, selHypo, selAlgo;
156   myDlg->selectedObject( SMESHGUI_AddSubMeshDlg::MeshObj, selMesh );
157   myDlg->selectedObject( SMESHGUI_AddSubMeshDlg::GeomObj, selGeom );
158   myDlg->selectedObject( SMESHGUI_AddSubMeshDlg::Hypo, selHypo );
159   myDlg->selectedObject( SMESHGUI_AddSubMeshDlg::Algo, selAlgo );
160   
161   _PTR(Study) study = studyDS();
162   _PTR(SObject) aMeshSO = study->FindObjectID( selMesh.first() );
163   SMESH::SMESH_Mesh_var myMesh = SMESH::SMESH_Mesh::_narrow( _CAST( SObject, aMeshSO )->GetObject() );
164   GEOM::GEOM_Object_var myMainShape = SMESH::GetShapeOnMeshOrSubMesh(aMeshSO);
165   if (myMainShape->_is_nil())
166     return false;
167
168   SUIT_OverrideCursor wc;
169
170   _PTR(SObject) aGeomSO = study->FindObjectID( selGeom.first() );
171   GEOM::GEOM_Object_var myGeomShape = GEOM::GEOM_Object::_narrow( _CAST( SObject, aGeomSO )->GetObject() );
172   
173   // create submesh
174   SMESH::SMESH_subMesh_var aSubMesh = addSubMesh(myMesh, myGeomShape, myNameSubMesh);
175   int nbSuccess = 0;
176
177   if (!aSubMesh->_is_nil())
178   {
179     // assign hypotheses
180     int nbAlgo = selAlgo.count();
181     int nbHyps = selHypo.count() + nbAlgo;
182     for (int i = 0; i < nbHyps; i++)
183     {
184       _PTR(SObject) aHypSOClient =
185         study->FindObjectID
186           (i < nbAlgo ? selAlgo[i].latin1() : selHypo[i-nbAlgo].latin1());
187       if (aHypSOClient)
188       {
189         CORBA::Object_var anObject = _CAST(SObject,aHypSOClient)->GetObject();
190         if(!CORBA::is_nil(anObject))
191         {
192           SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow(anObject);
193           if(!aHyp->_is_nil())
194             if (SMESH::AddHypothesisOnSubMesh(aSubMesh, aHyp))
195               nbSuccess++;
196         }
197         else
198         {
199           SCRUTE(CORBA::is_nil(anObject));
200         }
201       }
202       else
203       {
204         SCRUTE(!aHypSOClient);
205       }
206     }
207   }
208   else
209   {
210     SCRUTE(aSubMesh->_is_nil());
211   }
212   
213   update( UF_Model | UF_ObjBrowser );
214   initDialog();
215   
216   return (nbSuccess > 0);
217 }
218
219 //=================================================================================
220 // function : initDialog()
221 // purpose  :
222 //=================================================================================
223 void SMESHGUI_AddSubMeshOp::initDialog()
224 {
225   SMESHGUI_SelectionOp::initDialog();
226   if( myDlg )
227   {
228     myDlg->setSubMeshName( tr( "SMESH_SUBMESH" ) );
229     updateDialog();
230   }
231 }
232
233 //=================================================================================
234 // function : IsFatherOf()
235 // purpose  :
236 //=================================================================================
237 static bool IsFatherOf (_PTR(SObject) SO, _PTR(SObject) fatherSO)
238 {
239   if( SO && fatherSO )
240   {
241     _PTR(SObject) aSO = SO->GetFather();
242     while (aSO->GetID().length() >= fatherSO->GetID().length())
243     {
244       if (aSO->GetID() == fatherSO->GetID())
245         return true;
246       aSO = aSO->GetFather();
247     }
248   }
249   return false;
250 }
251
252 //=================================================================================
253 // function : onSelectionChanged()
254 // purpose  :
255 //=================================================================================
256 void SMESHGUI_AddSubMeshOp::onSelectionChanged( int id )
257 {
258   if( !myDlg->hasSelection( id ) )
259     return;
260     
261   if( id==SMESHGUI_AddSubMeshDlg::MeshObj )
262     myDlg->clearSelection( SMESHGUI_AddSubMeshDlg::GeomObj );
263
264   else if( id==SMESHGUI_AddSubMeshDlg::GeomObj )
265   {
266     QStringList selMesh, selGeom;
267     myDlg->selectedObject( SMESHGUI_AddSubMeshDlg::MeshObj, selMesh );
268     myDlg->selectedObject( SMESHGUI_AddSubMeshDlg::GeomObj, selGeom );
269     
270     _PTR(SObject) aMeshSO = studyDS()->FindObjectID( selMesh.first() );
271     
272     GEOM::GEOM_Object_var aMainGeomShape = SMESH::GetShapeOnMeshOrSubMesh(aMeshSO);
273     _PTR(SObject) aMainGeomShapeSO = SMESH::FindSObject(aMainGeomShape);
274     if( !aMainGeomShapeSO || !IsFatherOf( studyDS()->FindObjectID( selGeom.first() ), aMainGeomShapeSO ) )
275       myDlg->clearSelection( id );
276   }
277 }
278
279 //=================================================================================
280 // function : addSubMesh()
281 // purpose  :
282 //=================================================================================
283 SMESH::SMESH_subMesh_var SMESHGUI_AddSubMeshOp::addSubMesh( SMESH::SMESH_Mesh_ptr theMesh,
284                                                             GEOM::GEOM_Object_ptr theShapeObject,
285                                                             const QString& theMeshName )
286 {
287   SMESH::SMESH_subMesh_var aSubMesh;
288   try
289   {
290     if(!theMesh->_is_nil() && !theShapeObject->_is_nil())
291       aSubMesh = theMesh->GetSubMesh(theShapeObject, theMeshName);
292   }
293   catch (const SALOME::SALOME_Exception& S_ex)
294   {
295     SalomeApp_Tools::QtCatchCorbaException(S_ex);
296   }
297
298   return aSubMesh._retn();
299 }
300
301 //=================================================================================
302 // function : updateDialog()
303 // purpose  :
304 //=================================================================================
305 void SMESHGUI_AddSubMeshOp::updateDialog()
306 {
307   if( !myDlg )
308     return;
309     
310   bool isEnabled = !myDlg->subMeshName().isEmpty() &&
311                    myDlg->hasSelection( SMESHGUI_AddSubMeshDlg::MeshObj ) &&
312                    myDlg->hasSelection( SMESHGUI_AddSubMeshDlg::GeomObj ) &&
313                    myDlg->hasSelection( SMESHGUI_AddSubMeshDlg::Hypo ) &&
314                    myDlg->hasSelection( SMESHGUI_AddSubMeshDlg::Algo );
315
316   bool isImportedMesh = false;
317
318   QStringList selMesh;
319   myDlg->selectedObject( SMESHGUI_AddSubMeshDlg::MeshObj, selMesh );
320   _PTR(SObject) SO = studyDS()->FindObjectID( selMesh.first() );
321   GEOM::GEOM_Object_var myGeomShape = SMESH::GetShapeOnMeshOrSubMesh(SO);
322   isImportedMesh = myGeomShape->_is_nil();
323
324   isEnabled = isEnabled && !isImportedMesh;
325   
326   myDlg->setButtonEnabled( isEnabled, QtxDialog::OK | QtxDialog::Apply );
327 }
328
329 //=================================================================================
330 // function : onNameChanged()
331 // purpose  :
332 //=================================================================================
333 void SMESHGUI_AddSubMeshOp::onNameChanged( const QString& )
334 {
335   updateDialog();
336 }