Salome HOME
Merge from V5_1_4_BR 07/05/2010
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_MeshOrderOp.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
20 // File   : SMESHGUI_MeshOrderOp.cxx
21 // Author : Pavel TELKOV, Open CASCADE S.A.S.
22 //
23 #include "SMESHGUI_MeshOrderOp.h"
24
25 #include "SMESHGUI.h"
26 #include "SMESHGUI_Utils.h"
27 #include "SMESHGUI_MeshUtils.h"
28
29 // SALOME GUI includes
30 #include <LightApp_SelectionMgr.h>
31 #include <SALOME_ListIO.hxx>
32 #include <SUIT_ResourceMgr.h>
33 #include <SUIT_OverrideCursor.h>
34 #include <SUIT_MessageBox.h>
35 #include <SUIT_Desktop.h>
36
37 // SALOME KERNEL includes
38 #include <SALOMEDS_SObject.hxx>
39 #include <SALOMEDSClient_SObject.hxx>
40
41 // STL includes
42 #include <set>
43
44 //================================================================================
45 /*!
46  * \brief Constructor
47 */
48 //================================================================================
49
50 SMESHGUI_MeshOrderOp::SMESHGUI_MeshOrderOp()
51   : SMESHGUI_Operation(), myDlg(0), myMgr(0)
52 {
53   myDlg = new SMESHGUI_MeshOrderDlg( desktop() );
54   
55   myHelpFileName = "constructing_meshes_page.html#mesh_order_anchor";
56 }
57
58 //================================================================================
59 /*!
60  * \brief Destructor
61 */
62 //================================================================================
63
64 SMESHGUI_MeshOrderOp::~SMESHGUI_MeshOrderOp()
65 {
66 }
67
68 //================================================================================
69 /*!
70  * \brief Return operation dialog
71  */
72 //================================================================================
73
74 LightApp_Dialog* SMESHGUI_MeshOrderOp::dlg() const
75 {
76   return myDlg;
77 }
78
79 //================================================================================
80 /*!
81  * \brief perform it's intention action: compute 2D mesh on 3D
82  */
83 //================================================================================
84
85 void SMESHGUI_MeshOrderOp::startOperation()
86 {
87   SMESHGUI_Operation::startOperation();
88   if (myMgr)
89     myDlg->show();
90 }
91
92 //================================================================================
93 /*!
94  * \brief Init dialog and mesh order box
95  */
96 //================================================================================
97
98 void SMESHGUI_MeshOrderOp::initDialog()
99 {
100   if (!myDlg )
101     return;
102   
103   SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_nil();
104   // check selection
105   LightApp_SelectionMgr *Sel = selectionMgr();
106   SALOME_ListIO selected; Sel->selectedObjects( selected );
107
108   if (selected.Extent() == 1)
109     aMesh = SMESH::GetMeshByIO(selected.First());
110   if (aMesh->_is_nil()) {
111     SUIT_MessageBox::warning(desktop(),
112                              tr("SMESH_WRN_WARNING"),
113                              tr("SMESH_WRN_NO_AVAILABLE_DATA"));
114     onCancel();
115     return;
116   }
117
118   myMgr = new SMESHGUI_MeshOrderMgr( myDlg->GetMeshOrderBox() );
119   myMgr->SetMesh( aMesh );
120   if ( !myMgr->GetMeshOrder() ) {
121     SUIT_MessageBox::information(desktop(),
122                              tr("SMESH_INFORMATION"),
123                              tr("SMESH_NO_CONCURENT_MESH"));
124     
125     onCancel();
126     return;
127   }
128 }
129
130 //================================================================================
131 /*!
132  * \brief Apply changes
133  */
134 //================================================================================
135
136 bool SMESHGUI_MeshOrderOp::onApply()
137 {
138   SUIT_OverrideCursor aWaitCursor;
139   bool res = myMgr ? myMgr->SetMeshOrder() : false;
140
141   delete myMgr;
142   myMgr = 0;
143
144   return res;
145 }
146
147 //================================================================================
148 /*!
149  * \brief Apply changes
150  */
151 //================================================================================
152
153 void SMESHGUI_MeshOrderOp::onCancel()
154 {
155   delete myMgr;
156   myMgr = 0;
157
158   abort();
159 }
160
161 //================================================================================
162 /*!
163  * \brief Constructor
164 */
165 //================================================================================
166
167 SMESHGUI_MeshOrderMgr::SMESHGUI_MeshOrderMgr( SMESHGUI_MeshOrderBox* theBox )
168 : myBox( theBox )
169 {
170   myMesh = SMESH::SMESH_Mesh::_nil();
171 }
172
173 //================================================================================
174 /*!
175  * \brief Destructor
176 */
177 //================================================================================
178
179 SMESHGUI_MeshOrderMgr::~SMESHGUI_MeshOrderMgr()
180 {
181 }
182
183 //================================================================================
184 /*!
185  * \brief Set root mesh object
186  */
187 //================================================================================
188
189 void SMESHGUI_MeshOrderMgr::SetMesh(SMESH::SMESH_Mesh_var& theMesh)
190 {
191   myMesh = SMESH::SMESH_Mesh::_duplicate(theMesh);
192   _PTR(SObject) aMeshSObj = SMESH::FindSObject(theMesh);
193   if ( myBox && aMeshSObj )
194     myBox->setTitle( aMeshSObj->GetName().c_str() );
195 }  
196
197 //================================================================================
198 /*!
199  * \brief Check for concurents between submesh objects
200  */
201 //================================================================================
202
203 bool SMESHGUI_MeshOrderMgr::GetMeshOrder()
204 {
205   ListListId   idListList;
206   return GetMeshOrder(idListList);
207 }
208
209 //================================================================================
210 /*!
211  * \brief Check for concurents between submesh objects
212  */
213 //================================================================================
214
215 bool SMESHGUI_MeshOrderMgr::GetMeshOrder(ListListId& theIdListList)
216 {
217   if (!myBox || myMesh->_is_nil())
218     return false;
219   myBox->Clear();
220   SMESH::submesh_array_array_var meshOrder = myMesh->GetMeshOrder();
221   if ( !meshOrder.operator->() || !meshOrder->length() )
222     return false;
223   ListListName nameListList;
224   for ( int i = 0, n = meshOrder->length(); i < n; i++ )
225   {
226     QList<int> idList;
227     QStringList nameList;
228     const SMESH::submesh_array& aSMArray = meshOrder[i];
229     for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
230     {
231       const SMESH::SMESH_subMesh_var subMesh = aSMArray[j];
232       
233       _PTR(SObject) aSubMeshSObj = SMESH::FindSObject(subMesh);
234       if ( !aSubMeshSObj )
235         continue;
236
237       idList.append(subMesh->GetId() );
238       nameList.append( QString(aSubMeshSObj->GetName().c_str()) );
239     }
240     theIdListList.append(idList);
241     nameListList.append(nameList);
242   }
243   myBox->SetMeshes(nameListList, theIdListList);
244   return !theIdListList.isEmpty();
245 }
246
247 //================================================================================
248 /*!
249  * \brief Returns status is order changed by user
250  */
251 //================================================================================
252
253 bool SMESHGUI_MeshOrderMgr::IsOrderChanged() const
254 {
255   return myBox && myBox->IsOrderChanged();
256 }
257
258 //================================================================================
259 /*!
260  * \brief Store submesh priority order
261  */
262 //================================================================================
263
264 bool SMESHGUI_MeshOrderMgr::SetMeshOrder()
265 {
266   return myBox ? SetMeshOrder(myBox->GetMeshIds()) : false;
267 }
268
269 //================================================================================
270 /*!
271  * \brief Store submesh priority order
272  */
273 //================================================================================
274
275 bool SMESHGUI_MeshOrderMgr::SetMeshOrder( const  ListListId& theListListIds )
276 {
277   if (theListListIds.isEmpty() || myMesh->_is_nil())
278     return false;
279
280   _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
281   _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh);
282   if ( !aStudy || !aMeshSObj )
283     return false;
284
285   std::map<int, SMESH::SMESH_subMesh_var> mapOfSubMesh;
286   for (int i = SMESH::Tag_FirstSubMesh; i <= SMESH::Tag_LastSubMesh; i++) {
287     _PTR(SObject) aSubmeshRoot;
288     if ( !aMeshSObj->FindSubObject( i, aSubmeshRoot ) )
289       continue;
290     _PTR(ChildIterator) smIter = aStudy->NewChildIterator( aSubmeshRoot );
291     for ( ; smIter->More(); smIter->Next() ) {
292       _PTR(SObject) aSmObj = smIter->Value();
293       SMESH::SMESH_subMesh_var sm =
294         SMESH::SObjectToInterface<SMESH::SMESH_subMesh>( aSmObj );
295       mapOfSubMesh[ sm->GetId() ] = SMESH::SMESH_subMesh::_duplicate(sm);
296     }
297   }
298
299   // is it enought to set modifid attribute on root mesh objects only?
300   //  it is seems that modifaction flag will be set on child submeshes 
301   //  automatically  (see SMESH::ModifiedMesh for details)
302   SMESH::ModifiedMesh( aMeshSObj, false, false );
303
304   SMESH::submesh_array_array_var meshOrder = new SMESH::submesh_array_array();
305   meshOrder->length(theListListIds.count() );
306   ListListId::const_iterator it = theListListIds.constBegin();
307   for ( int i = 0; it != theListListIds.constEnd(); ++it ) {
308     const QList<int>& ids = *it;
309     SMESH::submesh_array_var subMeshList = new SMESH::submesh_array();
310     subMeshList->length( ids.count() );
311     QList<int>::const_iterator subIt = ids.constBegin();
312     for( int j = 0; subIt != ids.constEnd(); ++subIt )
313       if ( mapOfSubMesh.find( *subIt ) != mapOfSubMesh.end() )
314         subMeshList[ j++ ] = mapOfSubMesh[ *subIt ];
315
316     meshOrder[ i++ ] = subMeshList;
317   }
318   // update object browser
319   SMESHGUI::GetSMESHGUI()->updateObjBrowser( true, 0 );
320
321   return myMesh->SetMeshOrder(meshOrder);
322 }