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