Salome HOME
64da71a7fb7508a540ba5b2065ccdf0cb8c8e27a
[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_AddSubMeshDlg.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_Operation(),
59   myDlg( 0 ),
60   myMeshFilter( 0 ),
61   myGeomFilter( 0 ),
62   myHypothesisFilter( 0 ),
63   myAlgorithmFilter( 0 )
64 {
65 }
66
67 //=================================================================================
68 // function : Destructor
69 // purpose  :
70 //=================================================================================
71 SMESHGUI_AddSubMeshOp::~SMESHGUI_AddSubMeshOp()
72 {
73   if( myDlg )
74     delete myDlg;
75
76   if( myMeshFilter )
77     delete myMeshFilter;
78         
79   if( myGeomFilter )
80     delete myGeomFilter;
81   
82   if( myAlgorithmFilter )
83     delete myAlgorithmFilter;
84
85   if( myHypothesisFilter )
86     delete myHypothesisFilter;    
87 }
88
89 //=================================================================================
90 // function : startOperation
91 // purpose  :
92 //=================================================================================
93 void SMESHGUI_AddSubMeshOp::startOperation()
94 {
95   if( !myDlg )
96   {
97     myDlg = new SMESHGUI_AddSubMeshDlg( getSMESHGUI() );
98     connect( myDlg, SIGNAL( objectActivated( int ) ), this, SLOT( onActivateObject( int ) ) );
99     connect( myDlg, SIGNAL( selectionChanged( int ) ), this, SLOT( onSelectionChanged( int ) ) );
100   }
101
102   SMESHGUI_Operation::startOperation();
103
104   if( !myGeomFilter )
105   {
106     TColStd_MapOfInteger allTypesMap;
107     for (int i = 0; i < 10; i++)
108       allTypesMap.Add(i);
109     myGeomFilter       = new SMESH_NumberFilter ("GEOM", TopAbs_SHAPE, 0, allTypesMap);
110   }
111
112   if( !myMeshFilter )
113     myMeshFilter       = new SMESH_TypeFilter (MESH);
114     
115   if( !myAlgorithmFilter )
116     myAlgorithmFilter  = new SMESH_TypeFilter (ALGORITHM);
117
118   if( !myHypothesisFilter )
119     myHypothesisFilter = new SMESH_TypeFilter (HYPOTHESIS);
120     
121   init();
122   myDlg->show();
123 }
124
125 //=================================================================================
126 // function : dlg
127 // purpose  :
128 //=================================================================================
129 SalomeApp_Dialog* SMESHGUI_AddSubMeshOp::dlg() const
130 {
131   return myDlg;
132 }
133
134 //=================================================================================
135 // function : selectionDone
136 // purpose  :
137 //=================================================================================
138 void SMESHGUI_AddSubMeshOp::selectionDone()
139 {
140   QStringList names, ids;
141   SMESHGUI_Dialog::TypesList types;
142   selected( names, types, ids );
143   if( myDlg )
144   {
145     myDlg->selectObject( names, types, ids );
146     myDlg->updateControlState( isValid() );
147   }
148 }
149
150 //=================================================================================
151 // function : onActivateObject
152 // purpose  :
153 //=================================================================================
154 void SMESHGUI_AddSubMeshOp::onActivateObject( int obj )
155 {
156   SalomeApp_SelectionMgr* mgr = selectionMgr();
157
158   if( !mgr )
159     return;
160     
161   mgr->clearFilters();
162
163   if( obj==SMESHGUI_AddSubMeshDlg::MeshObj )
164     mgr->installFilter( myMeshFilter );
165
166   else if( obj==SMESHGUI_AddSubMeshDlg::GeomObj )
167     mgr->installFilter( myGeomFilter );
168     
169   else if( obj==SMESHGUI_AddSubMeshDlg::Hypo )
170     mgr->installFilter( myHypothesisFilter );
171
172   else if( obj==SMESHGUI_AddSubMeshDlg::Algo )
173     mgr->installFilter( myAlgorithmFilter );
174 }
175
176 //=================================================================================
177 // function : commitOperation
178 // purpose  :
179 //=================================================================================
180 bool SMESHGUI_AddSubMeshOp::onApply()
181 {
182   if( getSMESHGUI()->isActiveStudyLocked() )
183     return false;
184
185   QString myNameSubMesh = myDlg->subMeshName();
186   if (myNameSubMesh.isEmpty())
187   {
188     SUIT_MessageBox::warn1( dlg(), tr("SMESH_WRN_WARNING"),
189                             tr("SMESH_WRN_EMPTY_NAME"), tr("SMESH_BUT_OK"));
190     return false;
191   }
192
193   QStringList selMesh, selGeom, selHypo, selAlgo;
194   myDlg->selectedObject( SMESHGUI_AddSubMeshDlg::MeshObj, selMesh );
195   myDlg->selectedObject( SMESHGUI_AddSubMeshDlg::GeomObj, selGeom );
196   myDlg->selectedObject( SMESHGUI_AddSubMeshDlg::Hypo, selHypo );
197   myDlg->selectedObject( SMESHGUI_AddSubMeshDlg::Algo, selAlgo );
198   
199   _PTR(Study) study = studyDS();
200   _PTR(SObject) aMeshSO = study->FindObjectID( selMesh.first() );
201   SMESH::SMESH_Mesh_var myMesh = SMESH::SMESH_Mesh::_narrow( _CAST( SObject, aMeshSO )->GetObject() );
202   GEOM::GEOM_Object_var myMainShape = SMESH::GetShapeOnMeshOrSubMesh(aMeshSO);
203   if (myMainShape->_is_nil())
204     return false;
205
206   SUIT_OverrideCursor wc;
207
208   _PTR(SObject) aGeomSO = study->FindObjectID( selGeom.first() );
209   GEOM::GEOM_Object_var myGeomShape = GEOM::GEOM_Object::_narrow( _CAST( SObject, aGeomSO )->GetObject() );
210   
211   // create submesh
212   SMESH::SMESH_subMesh_var aSubMesh = addSubMesh(myMesh, myGeomShape, myNameSubMesh);
213   int nbSuccess = 0;
214
215   if (!aSubMesh->_is_nil())
216   {
217     // assign hypotheses
218     int nbAlgo = selAlgo.count();
219     int nbHyps = selHypo.count() + nbAlgo;
220     for (int i = 0; i < nbHyps; i++)
221     {
222       _PTR(SObject) aHypSOClient =
223         study->FindObjectID
224           (i < nbAlgo ? selAlgo[i].latin1() : selHypo[i-nbAlgo].latin1());
225       if (aHypSOClient)
226       {
227         CORBA::Object_var anObject = _CAST(SObject,aHypSOClient)->GetObject();
228         if(!CORBA::is_nil(anObject))
229         {
230           SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow(anObject);
231           if(!aHyp->_is_nil())
232             if (SMESH::AddHypothesisOnSubMesh(aSubMesh, aHyp))
233               nbSuccess++;
234         }
235         else
236         {
237           SCRUTE(CORBA::is_nil(anObject));
238         }
239       }
240       else
241       {
242         SCRUTE(!aHypSOClient);
243       }
244     }
245   }
246   else
247   {
248     SCRUTE(aSubMesh->_is_nil());
249   }
250   
251   update( UF_Model | UF_ObjBrowser );
252   init();
253   
254   return (nbSuccess > 0);
255 }
256
257 //=================================================================================
258 // function : init()
259 // purpose  :
260 //=================================================================================
261 void SMESHGUI_AddSubMeshOp::init()
262 {
263   if( myDlg )
264   {    
265     myDlg->init();
266     myDlg->updateControlState( false );
267   }
268 }
269
270 //=================================================================================
271 // function : isValid()
272 // purpose  :
273 //=================================================================================
274 bool SMESHGUI_AddSubMeshOp::isValid() const
275 {
276   bool isEnabled = !myDlg->subMeshName().isEmpty() &&
277                    myDlg->hasSelection( SMESHGUI_AddSubMeshDlg::MeshObj ) &&
278                    myDlg->hasSelection( SMESHGUI_AddSubMeshDlg::GeomObj ) &&
279                    myDlg->hasSelection( SMESHGUI_AddSubMeshDlg::Hypo ) &&
280                    myDlg->hasSelection( SMESHGUI_AddSubMeshDlg::Algo );
281                    
282   bool isImportedMesh = false;
283
284   QStringList selMesh;
285   myDlg->selectedObject( SMESHGUI_AddSubMeshDlg::MeshObj, selMesh );
286   _PTR(SObject) SO = studyDS()->FindObjectID( selMesh.first() );
287   GEOM::GEOM_Object_var myGeomShape = SMESH::GetShapeOnMeshOrSubMesh(SO);
288   isImportedMesh = myGeomShape->_is_nil();
289
290   return isEnabled && !isImportedMesh;
291 }
292
293 //=================================================================================
294 // function : IsFatherOf()
295 // purpose  :
296 //=================================================================================
297 static bool IsFatherOf (_PTR(SObject) SO, _PTR(SObject) fatherSO)
298 {
299   if( SO && fatherSO )
300   {
301     _PTR(SObject) aSO = SO->GetFather();
302     while (aSO->GetID().length() >= fatherSO->GetID().length())
303     {
304       if (aSO->GetID() == fatherSO->GetID())
305         return true;
306       aSO = aSO->GetFather();
307     }
308   }
309   return false;
310 }
311
312 //=================================================================================
313 // function : onSelectionChanged()
314 // purpose  :
315 //=================================================================================
316 void SMESHGUI_AddSubMeshOp::onSelectionChanged( int id )
317 {
318   if( !myDlg->hasSelection( id ) )
319     return;
320     
321   if( id==SMESHGUI_AddSubMeshDlg::MeshObj )
322     myDlg->clearSelection( SMESHGUI_AddSubMeshDlg::GeomObj );
323
324   else if( id==SMESHGUI_AddSubMeshDlg::GeomObj )
325   {
326     QStringList selMesh, selGeom;
327     myDlg->selectedObject( SMESHGUI_AddSubMeshDlg::MeshObj, selMesh );
328     myDlg->selectedObject( SMESHGUI_AddSubMeshDlg::GeomObj, selGeom );
329     
330     _PTR(SObject) aMeshSO = studyDS()->FindObjectID( selMesh.first() );
331     
332     GEOM::GEOM_Object_var aMainGeomShape = SMESH::GetShapeOnMeshOrSubMesh(aMeshSO);
333     _PTR(SObject) aMainGeomShapeSO = SMESH::FindSObject(aMainGeomShape);
334     if( !aMainGeomShapeSO || !IsFatherOf( studyDS()->FindObjectID( selGeom.first() ), aMainGeomShapeSO ) )
335       myDlg->clearSelection( id );
336   }
337 }
338
339 //=================================================================================
340 // function : onSelectionChanged()
341 // purpose  :
342 //=================================================================================
343 SMESH::SMESH_subMesh_var SMESHGUI_AddSubMeshOp::addSubMesh( SMESH::SMESH_Mesh_ptr theMesh,
344                                                             GEOM::GEOM_Object_ptr theShapeObject,
345                                                             const QString& theMeshName )
346 {
347   SMESH::SMESH_subMesh_var aSubMesh;
348   try
349   {
350     if(!theMesh->_is_nil() && !theShapeObject->_is_nil())
351       aSubMesh = theMesh->GetSubMesh(theShapeObject, theMeshName);
352   }
353   catch (const SALOME::SALOME_Exception& S_ex)
354   {
355     SalomeApp_Tools::QtCatchCorbaException(S_ex);
356   }
357
358   return aSubMesh._retn();
359 }