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