Salome HOME
01b64b3a4010be8f21de4bd98a6462ceab2ea2dd
[modules/smesh.git] / src / StdMeshersGUI / StdMeshersGUI_EdgeDirectionParamWdg.cxx
1 //  Copyright (C) 2007-2008  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   : StdMeshersGUI_EdgeDirectionParamWdg.cxx
23 // Author : Open CASCADE S.A.S. (dmv)
24 // SMESH includes
25 //
26 #include "StdMeshersGUI_EdgeDirectionParamWdg.h"
27
28 // SMESH Includes
29 #include <SMESH_Type.h>
30 #include "SMESHGUI_MeshUtils.h"
31 #include <SMESH_Actor.h>
32 #include <SMESH_PreviewActorsCollection.h>
33 #include <SMESH_ActorUtils.h>
34 #include "SMESHGUI_GroupUtils.h"
35 #include "SMESH_Gen_i.hxx"
36 #include "SMESHGUI_GEOMGenUtils.h"
37
38 // SVTK Includes
39 #include <SVTK_ViewWindow.h>
40 #include <SVTK_ViewModel.h>
41 #include <SVTK_ViewWindow.h>
42 #include <SVTK_Selector.h>
43
44 // SALOME GUI includes
45 #include <SALOME_ListIO.hxx>
46 #include <LightApp_SelectionMgr.h>
47 #include <SALOME_ListIteratorOfListIO.hxx>
48
49 // SUIT Includes
50 #include <SUIT_ResourceMgr.h>
51
52 // GEOM Includes
53 #include <GEOMBase.h>
54
55 // Qt includes
56 #include <QPushButton>
57 #include <QGridLayout>
58 #include <QListWidget>
59 #include <QCheckBox>
60 #include <QLineEdit>
61
62 // OCCT includes
63 #include <TColStd_MapOfInteger.hxx>
64 #include <TColStd_IndexedMapOfInteger.hxx>
65 #include <TopoDS_Shape.hxx>
66 #include <TopExp.hxx>
67 #include <TopExp_Explorer.hxx>
68
69 // SALOME KERNEL includes
70 #include <SALOMEDS_SObject.hxx>
71
72 #define SPACING 6
73 #define MARGIN 0
74
75 //================================================================================
76 /*!
77  *  Constructor
78  */
79 //================================================================================
80
81 StdMeshersGUI_EdgeDirectionParamWdg
82 ::StdMeshersGUI_EdgeDirectionParamWdg( QWidget * parent ): 
83   QWidget( parent )
84 {
85   QPixmap image0( SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap( "SMESH", tr( "ICON_SELECT" ) ) );
86
87   QGridLayout* edgesLayout = new QGridLayout( this );
88   edgesLayout->setMargin( MARGIN );
89   edgesLayout->setSpacing( SPACING );
90   
91   myListWidget    = new QListWidget( this );
92   myAddButton    = new QPushButton( tr( "SMESH_BUT_ADD" ),    this );
93   myRemoveButton = new QPushButton( tr( "SMESH_BUT_REMOVE" ), this );      
94   myListWidget->setSelectionMode( QListWidget::ExtendedSelection );
95
96   edgesLayout->addWidget(myListWidget,   0, 0, 3, 3);
97   edgesLayout->addWidget(myAddButton,    0, 4);
98   edgesLayout->addWidget(myRemoveButton, 1, 4);
99
100   edgesLayout->setRowStretch(2, 5);
101   edgesLayout->setColumnStretch(2, 5);
102
103   setLayout( edgesLayout );
104   setMinimumWidth( 300 );
105
106   init();
107 }
108
109 //================================================================================
110 /*!
111  *  Destructor
112  */
113 //================================================================================
114
115 StdMeshersGUI_EdgeDirectionParamWdg::~StdMeshersGUI_EdgeDirectionParamWdg()
116 {
117   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) {
118     myPreviewActor->RemoveFromRender( myRenderer );
119     aViewWindow->Repaint();
120   }
121   myEntry = "";
122   myParamValue = "";
123   myMainShape.Nullify();
124   
125   delete myPreviewActor;
126 }
127
128 //================================================================================
129 /*!
130  *  Create a layout, initialize fields
131  */
132 //================================================================================
133
134 void StdMeshersGUI_EdgeDirectionParamWdg::init()
135 {
136   myParamValue = "";
137   myListOfIDs.clear();
138   mySelectedIDs.clear();
139
140   mySMESHGUI     = SMESHGUI::GetSMESHGUI();
141   mySelectionMgr = SMESH::GetSelectionMgr( mySMESHGUI );
142   mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
143
144   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
145     aViewWindow->SetSelectionMode( ActorSelection );
146
147   connect( myAddButton,    SIGNAL(clicked()), SLOT(onAdd()));
148   connect( myRemoveButton, SIGNAL(clicked()), SLOT(onRemove()));
149   
150   connect( mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
151   connect( myListWidget,   SIGNAL(itemSelectionChanged()),    this, SLOT(onListSelectionChanged()));
152
153   updateState();
154 }
155
156 //================================================================================
157 /*!
158  *  Create a layout, initialize fields
159  */
160 //================================================================================
161
162 void StdMeshersGUI_EdgeDirectionParamWdg::showPreview( bool visible)
163 {
164   if ( myIsShown != visible ) {
165     myPreviewActor->SetShown( visible );
166     
167     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
168       aViewWindow->Repaint();
169
170     myIsShown = visible;
171   }
172 }
173
174 //=================================================================================
175 // function : SelectionIntoArgument()
176 // purpose  : Called when selection as changed or other case
177 //=================================================================================
178 void StdMeshersGUI_EdgeDirectionParamWdg::SelectionIntoArgument()
179 {
180   mySelectedIDs.clear();
181
182   // get selected mesh
183   SALOME_ListIO aList;
184   mySelectionMgr->selectedObjects( aList );
185   int nbSel = aList.Extent();
186
187   if (nbSel < 1)
188     return;
189
190   SALOME_ListIteratorOfListIO anIt (aList);
191     
192   for ( ; anIt.More(); anIt.Next()) { // Loop on selected objects
193     Handle(SALOME_InteractiveObject) IO = anIt.Value();
194
195     GEOM::GEOM_Object_var aGeomObj = GetGeomObjectByEntry( IO->getEntry() );  
196     if ( !CORBA::is_nil( aGeomObj ) ) { // Selected Object From Study
197       GEOM::GEOM_Object_ptr aGeomFatherObj = aGeomObj->GetMainShape();
198       QString aFatherEntry = "";
199       QString aMainFatherEntry = "";
200       TopoDS_Shape shape;
201       if ( !CORBA::is_nil( aGeomFatherObj ) ) {
202         // Get Main Shape
203         GEOM::GEOM_Object_var aGeomMain = GetGeomObjectByEntry( myEntry );
204         if ( !CORBA::is_nil( aGeomMain ) || aGeomMain->GetType() == 37 ) {  // Main Shape is a Group
205           GEOM::GEOM_Object_ptr aMainFatherObj = aGeomMain->GetMainShape();
206           if ( !CORBA::is_nil( aMainFatherObj ) )
207             aMainFatherEntry = aMainFatherObj->GetStudyEntry();
208         }
209         aFatherEntry = aGeomFatherObj->GetStudyEntry();
210       }
211       
212       if ( aFatherEntry != "" && ( aFatherEntry == myEntry || aFatherEntry == aMainFatherEntry ) ) {
213         if ( aGeomObj->GetType() == 37 /*GEOM_GROUP*/ ) { // Selected Group that belongs the main object
214           GEOMBase::GetShape(aGeomObj, shape); 
215           if ( !shape.IsNull() ) {
216             TopExp_Explorer exp( shape, TopAbs_EDGE );
217             for ( ; exp.More(); exp.Next() ) {
218               int index = myPreviewActor->GetIndexByShape( exp.Current() );
219               if ( index ) {
220                 mySelectedIDs.append( index );
221                 myPreviewActor->HighlightID( index );
222               }
223             }
224           }
225         } else if ( aGeomObj->GetType() == 28 /*GEOM_SUBSHAPE*/  ) {
226           GEOMBase::GetShape(aGeomObj, shape); 
227           if ( !shape.IsNull() && shape.ShapeType() == TopAbs_EDGE ) {
228             int index = myPreviewActor->GetIndexByShape( shape );
229             if ( index ) {
230               mySelectedIDs.append( index );
231               myPreviewActor->HighlightID( index );
232             }
233           }
234         }
235       }
236     } else { // Selected Actor from Actor Collection
237       QString anEntry = IO->getEntry();
238       QString str = "_";
239       int index = anEntry.lastIndexOf( str );
240       anEntry.remove(0, index+1);
241       int ind = anEntry.toInt();
242       if ( ind )
243         mySelectedIDs.append( ind );
244     }
245   }
246 }
247
248 //=================================================================================
249 // function : onAdd()
250 // purpose  : Called when Add Button Clicked
251 //=================================================================================
252 void StdMeshersGUI_EdgeDirectionParamWdg::onAdd()
253 {
254   if ( mySelectedIDs.size() < 1 )
255     return;
256
257   myListWidget->blockSignals( true );
258   for (int i = 0; i < mySelectedIDs.size(); i++) {
259     if ( myListOfIDs.indexOf( mySelectedIDs.at(i) ) == -1 ) {
260       QString anID = QString(" %1").arg( mySelectedIDs.at(i) );
261
262       QListWidgetItem* anItem = new QListWidgetItem( anID, myListWidget );
263       anItem->setSelected(true);
264       
265       myListOfIDs.append( mySelectedIDs.at(i) );
266     }
267   }
268   onListSelectionChanged();
269
270   myListWidget->blockSignals( false );
271 }
272          
273 //=================================================================================
274 // function : onRemove()
275 // purpose  : Called when Remove Button Clicked
276 //=================================================================================
277 void StdMeshersGUI_EdgeDirectionParamWdg::onRemove()
278 {
279   if ( myListWidget->count() < 1 )
280     return;
281
282   myListWidget->blockSignals( true );
283   QList<QListWidgetItem*> selItems = myListWidget->selectedItems();
284   QListWidgetItem* item;
285   foreach(item, selItems) {
286     QString idStr = item->text();
287     int id = idStr.toInt();
288
289     int index = myListOfIDs.indexOf( id );
290     myListOfIDs.removeAt( index );
291     delete item;
292   }
293
294   onListSelectionChanged();
295   myListWidget->blockSignals( false );
296 }
297
298 //=================================================================================
299 // function : onListSelectionChanged()
300 // purpose  : Called when selection in element list is changed
301 //=================================================================================
302 void StdMeshersGUI_EdgeDirectionParamWdg::onListSelectionChanged()
303 {
304   mySelectionMgr->clearSelected();
305   TColStd_MapOfInteger aIndexes;
306   QList<QListWidgetItem*> selItems = myListWidget->selectedItems();
307   QListWidgetItem* anItem;
308   foreach(anItem, selItems)
309     myPreviewActor->HighlightID( anItem->text().toInt() );
310 }
311
312 //=================================================================================
313 // function : setGeomShape
314 // purpose  : Called to set geometry
315 //================================================================================
316 void StdMeshersGUI_EdgeDirectionParamWdg::SetMainShapeEntry( const QString& theEntry )
317 {
318   if ( theEntry != "") {
319     myParamValue = theEntry;
320     myEntry = theEntry;
321     myMainShape = GetTopoDSByEntry( theEntry );
322     updateState();
323   }
324 }
325
326 //=================================================================================
327 // function : updateState
328 // purpose  : update Widget state
329 //=================================================================================
330 void StdMeshersGUI_EdgeDirectionParamWdg::updateState()
331 {
332   bool state = false;
333   if ( !myMainShape.IsNull() )
334     state = true;
335   
336   myListWidget->setEnabled( state );
337   myAddButton->setEnabled( state );
338   myRemoveButton->setEnabled( state );
339   
340   if (state = true) {
341     myPreviewActor = new SMESH_PreviewActorsCollection();
342     myPreviewActor->SetSelector( mySelector );
343     myPreviewActor->Init( myMainShape, TopAbs_EDGE, myEntry );
344     myPreviewActor->SetShown( false );
345     myIsShown = false;
346     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) {
347       myRenderer = aViewWindow->getRenderer();
348       myPreviewActor->AddToRender( myRenderer );
349       aViewWindow->Repaint();
350     }
351   }
352 }
353
354 //=================================================================================
355 // function : GetGeomObjectByEntry
356 // purpose  : Called to get GeomObject
357 //=================================================================================
358 GEOM::GEOM_Object_var StdMeshersGUI_EdgeDirectionParamWdg::GetGeomObjectByEntry( const QString& theEntry )
359 {
360   GEOM::GEOM_Object_var aGeomObj;
361   SALOMEDS::Study_var aStudy = SMESHGUI::GetSMESHGen()->GetCurrentStudy();
362   if (aStudy != 0) {
363     SALOMEDS::SObject_var aSObj = aStudy->FindObjectID( theEntry.toLatin1().data() );
364     SALOMEDS::GenericAttribute_var anAttr;
365
366     if (!aSObj->_is_nil() && aSObj->FindAttribute(anAttr, "AttributeIOR")) {
367       SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
368       CORBA::String_var aVal = anIOR->Value();
369       CORBA::Object_var obj = aStudy->ConvertIORToObject(aVal);
370       aGeomObj = GEOM::GEOM_Object::_narrow(obj);
371     }
372   }
373   return aGeomObj;
374 }
375
376 //=================================================================================
377 // function : setObjectByEntry
378 // purpose  : Called to get GeomObject
379 //=================================================================================
380 TopoDS_Shape StdMeshersGUI_EdgeDirectionParamWdg::GetTopoDSByEntry( const QString& theEntry )
381 {
382   TopoDS_Shape shape;
383   GEOM::GEOM_Object_var aGeomObj = GetGeomObjectByEntry( theEntry );
384   GEOMBase::GetShape(aGeomObj, shape);
385   return shape;
386 }
387
388 //=================================================================================
389 // function : GetListOfIds
390 // purpose  : Called to get the list of Edges IDs
391 //=================================================================================
392 SMESH::long_array_var StdMeshersGUI_EdgeDirectionParamWdg::GetListOfIDs()
393 {
394   SMESH::long_array_var anArray = new SMESH::long_array;
395   int size = myListOfIDs.size();
396   anArray->length( size );
397   if ( size ) {
398     for (int i = 0; i < size; i++) {
399         anArray[i] = myListOfIDs.at(i);
400     }
401   }
402   return anArray;
403 }
404
405 //=================================================================================
406 // function : SetListOfIds
407 // purpose  : Called to set the list of Edges IDs
408 //=================================================================================
409 void StdMeshersGUI_EdgeDirectionParamWdg::SetListOfIDs( SMESH::long_array_var theIds)
410 {
411   mySelectedIDs.clear();
412   myListOfIDs.clear();
413   int size = theIds->length();
414   for ( int i = 0; i < size; i++ )
415     mySelectedIDs.append( theIds[ i ] );
416   onAdd();
417 }