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