Salome HOME
Implementation of Quadrangle (Mapping) for faces built on 3 edges (0018911 from Mantis).
[modules/smesh.git] / src / StdMeshersGUI / StdMeshersGUI_SubShapeSelectorWdg.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_SubShapeSelectorWdg.cxx
23 // Author : Open CASCADE S.A.S. (dmv)
24 // SMESH includes
25 //
26 #include "StdMeshersGUI_SubShapeSelectorWdg.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_SubShapeSelectorWdg
82 ::StdMeshersGUI_SubShapeSelectorWdg( 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   myMaxSize = 1000;
107   mySubShType = TopAbs_EDGE;
108
109   init();
110 }
111
112 //================================================================================
113 /*!
114  *  Destructor
115  */
116 //================================================================================
117
118 StdMeshersGUI_SubShapeSelectorWdg::~StdMeshersGUI_SubShapeSelectorWdg()
119 {
120   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) {
121     myPreviewActor->RemoveFromRender( myRenderer );
122     aViewWindow->Repaint();
123   }
124   myEntry = "";
125   myParamValue = "";
126   myMainShape.Nullify();
127   
128   delete myPreviewActor;
129 }
130
131 //================================================================================
132 /*!
133  *  Create a layout, initialize fields
134  */
135 //================================================================================
136
137 void StdMeshersGUI_SubShapeSelectorWdg::init()
138 {
139   myParamValue = "";
140   myListOfIDs.clear();
141   mySelectedIDs.clear();
142
143   mySMESHGUI     = SMESHGUI::GetSMESHGUI();
144   mySelectionMgr = SMESH::GetSelectionMgr( mySMESHGUI );
145   mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
146
147   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
148     aViewWindow->SetSelectionMode( ActorSelection );
149
150   connect( myAddButton,    SIGNAL(clicked()), SLOT(onAdd()));
151   connect( myRemoveButton, SIGNAL(clicked()), SLOT(onRemove()));
152   
153   connect( mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
154   connect( myListWidget,   SIGNAL(itemSelectionChanged()),    this, SLOT(onListSelectionChanged()));
155
156   updateState();
157 }
158
159 //================================================================================
160 /*!
161  *  Create a layout, initialize fields
162  */
163 //================================================================================
164
165 void StdMeshersGUI_SubShapeSelectorWdg::showPreview( bool visible)
166 {
167   if ( myIsShown != visible ) {
168     myPreviewActor->SetShown( visible );
169     
170     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
171       aViewWindow->Repaint();
172
173     myIsShown = visible;
174   }
175 }
176
177 //=================================================================================
178 // function : SelectionIntoArgument()
179 // purpose  : Called when selection as changed or other case
180 //=================================================================================
181 void StdMeshersGUI_SubShapeSelectorWdg::SelectionIntoArgument()
182 {
183   mySelectedIDs.clear();
184
185   // get selected mesh
186   SALOME_ListIO aList;
187   mySelectionMgr->selectedObjects( aList );
188   int nbSel = aList.Extent();
189
190   if (nbSel < 1)
191     return;
192
193   SALOME_ListIteratorOfListIO anIt (aList);
194     
195   for ( ; anIt.More(); anIt.Next()) { // Loop on selected objects
196     Handle(SALOME_InteractiveObject) IO = anIt.Value();
197
198     GEOM::GEOM_Object_var aGeomObj = GetGeomObjectByEntry( IO->getEntry() );  
199     if ( !CORBA::is_nil( aGeomObj ) ) { // Selected Object From Study
200       GEOM::GEOM_Object_ptr aGeomFatherObj = aGeomObj->GetMainShape();
201       QString aFatherEntry = "";
202       QString aMainFatherEntry = "";
203       TopoDS_Shape shape;
204       if ( !CORBA::is_nil( aGeomFatherObj ) ) {
205         // Get Main Shape
206         GEOM::GEOM_Object_var aGeomMain = GetGeomObjectByEntry( myEntry );
207         if ( !CORBA::is_nil( aGeomMain ) && aGeomMain->GetType() == 37 ) {  // Main Shape is a Group
208           GEOM::GEOM_Object_ptr aMainFatherObj = aGeomMain->GetMainShape();
209           if ( !CORBA::is_nil( aMainFatherObj ) )
210             aMainFatherEntry = aMainFatherObj->GetStudyEntry();
211         }
212         aFatherEntry = aGeomFatherObj->GetStudyEntry();
213       }
214       
215       if ( aFatherEntry != "" && ( aFatherEntry == myEntry || aFatherEntry == aMainFatherEntry ) ) {
216         if ( aGeomObj->GetType() == 37 /*GEOM_GROUP*/ ) { // Selected Group that belongs the main object
217           GEOMBase::GetShape(aGeomObj, shape); 
218           if ( !shape.IsNull() ) {
219             TopExp_Explorer exp( shape, mySubShType );
220             for ( ; exp.More(); exp.Next() ) {
221               int index = myPreviewActor->GetIndexByShape( exp.Current() );
222               if ( index ) {
223                 mySelectedIDs.append( index );
224                 myPreviewActor->HighlightID( index );
225               }
226             }
227           }
228         } else if ( aGeomObj->GetType() == 28 /*GEOM_SUBSHAPE*/  ) {
229           GEOMBase::GetShape(aGeomObj, shape); 
230           if ( !shape.IsNull() && shape.ShapeType() == mySubShType ) {
231             int index = myPreviewActor->GetIndexByShape( shape );
232             if ( index ) {
233               mySelectedIDs.append( index );
234               myPreviewActor->HighlightID( index );
235             }
236           }
237         }
238       }
239     } else { // Selected Actor from Actor Collection
240       QString anEntry = IO->getEntry();
241       QString str = "_";
242       int index = anEntry.lastIndexOf( str );
243       anEntry.remove(0, index+1);
244       int ind = anEntry.toInt();
245       if ( ind )
246         mySelectedIDs.append( ind );
247     }
248   }
249 }
250
251 //=================================================================================
252 // function : onAdd()
253 // purpose  : Called when Add Button Clicked
254 //=================================================================================
255 void StdMeshersGUI_SubShapeSelectorWdg::onAdd()
256 {
257   if ( mySelectedIDs.size() < 1 )
258     return;
259
260   myListWidget->blockSignals( true );
261   for (int i = 0; i < mySelectedIDs.size(); i++) {
262     if ( myListOfIDs.indexOf( mySelectedIDs.at(i) ) == -1 ) {
263       QString anID = QString(" %1").arg( mySelectedIDs.at(i) );
264
265       QListWidgetItem* anItem = new QListWidgetItem( anID, myListWidget );
266       anItem->setSelected(true);
267       
268       myListOfIDs.append( mySelectedIDs.at(i) );
269     }
270   }
271   onListSelectionChanged();
272
273   myListWidget->blockSignals( false );
274
275   if( myListOfIDs.size() >= myMaxSize )
276     myAddButton->setEnabled( false );
277 }
278          
279 //=================================================================================
280 // function : onRemove()
281 // purpose  : Called when Remove Button Clicked
282 //=================================================================================
283 void StdMeshersGUI_SubShapeSelectorWdg::onRemove()
284 {
285   if ( myListWidget->count() < 1 )
286     return;
287
288   myListWidget->blockSignals( true );
289   QList<QListWidgetItem*> selItems = myListWidget->selectedItems();
290   QListWidgetItem* item;
291   foreach(item, selItems) {
292     QString idStr = item->text();
293     int id = idStr.toInt();
294
295     int index = myListOfIDs.indexOf( id );
296     myListOfIDs.removeAt( index );
297     delete item;
298   }
299
300   onListSelectionChanged();
301   myListWidget->blockSignals( false );
302   
303   myAddButton->setEnabled( true );
304 }
305
306 //=================================================================================
307 // function : onListSelectionChanged()
308 // purpose  : Called when selection in element list is changed
309 //=================================================================================
310 void StdMeshersGUI_SubShapeSelectorWdg::onListSelectionChanged()
311 {
312   mySelectionMgr->clearSelected();
313   TColStd_MapOfInteger aIndexes;
314   QList<QListWidgetItem*> selItems = myListWidget->selectedItems();
315   QListWidgetItem* anItem;
316   foreach(anItem, selItems)
317     myPreviewActor->HighlightID( anItem->text().toInt() );
318 }
319
320 //=================================================================================
321 // function : setGeomShape
322 // purpose  : Called to set geometry
323 //================================================================================
324 void StdMeshersGUI_SubShapeSelectorWdg::SetMainShapeEntry( const QString& theEntry )
325 {
326   if ( theEntry != "") {
327     myParamValue = theEntry;
328     myEntry = theEntry;
329     myMainShape = GetTopoDSByEntry( theEntry );
330     updateState();
331   }
332 }
333
334 //=================================================================================
335 // function : updateState
336 // purpose  : update Widget state
337 //=================================================================================
338 void StdMeshersGUI_SubShapeSelectorWdg::updateState()
339 {
340   bool state = false;
341   if ( !myMainShape.IsNull() )
342     state = true;
343   
344   myListWidget->setEnabled( state );
345   myAddButton->setEnabled( state );
346   myRemoveButton->setEnabled( state );
347   
348   if (state = true) {
349     myPreviewActor = new SMESH_PreviewActorsCollection();
350     myPreviewActor->SetSelector( mySelector );
351     //myPreviewActor->Init( myMainShape, TopAbs_EDGE, myEntry );
352     myPreviewActor->Init( myMainShape, mySubShType, myEntry );
353     myPreviewActor->SetShown( false );
354     myIsShown = false;
355     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) {
356       myRenderer = aViewWindow->getRenderer();
357       myPreviewActor->AddToRender( myRenderer );
358       aViewWindow->Repaint();
359     }
360   }
361 }
362
363 //=================================================================================
364 // function : GetGeomObjectByEntry
365 // purpose  : Called to get GeomObject
366 //=================================================================================
367 GEOM::GEOM_Object_var StdMeshersGUI_SubShapeSelectorWdg::GetGeomObjectByEntry( const QString& theEntry )
368 {
369   GEOM::GEOM_Object_var aGeomObj;
370   SALOMEDS::Study_var aStudy = SMESHGUI::GetSMESHGen()->GetCurrentStudy();
371   if (aStudy != 0) {
372     SALOMEDS::SObject_var aSObj = aStudy->FindObjectID( theEntry.toLatin1().data() );
373     SALOMEDS::GenericAttribute_var anAttr;
374
375     if (!aSObj->_is_nil() && aSObj->FindAttribute(anAttr, "AttributeIOR")) {
376       SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
377       CORBA::String_var aVal = anIOR->Value();
378       CORBA::Object_var obj = aStudy->ConvertIORToObject(aVal);
379       aGeomObj = GEOM::GEOM_Object::_narrow(obj);
380     }
381   }
382   return aGeomObj;
383 }
384
385 //=================================================================================
386 // function : setObjectByEntry
387 // purpose  : Called to get GeomObject
388 //=================================================================================
389 TopoDS_Shape StdMeshersGUI_SubShapeSelectorWdg::GetTopoDSByEntry( const QString& theEntry )
390 {
391   TopoDS_Shape shape;
392   GEOM::GEOM_Object_var aGeomObj = GetGeomObjectByEntry( theEntry );
393   GEOMBase::GetShape(aGeomObj, shape);
394   return shape;
395 }
396
397 //=================================================================================
398 // function : GetListOfIds
399 // purpose  : Called to get the list of SubShapes IDs
400 //=================================================================================
401 SMESH::long_array_var StdMeshersGUI_SubShapeSelectorWdg::GetListOfIDs()
402 {
403   SMESH::long_array_var anArray = new SMESH::long_array;
404   int size = myListOfIDs.size();
405   anArray->length( size );
406   if ( size ) {
407     for (int i = 0; i < size; i++) {
408         anArray[i] = myListOfIDs.at(i);
409     }
410   }
411   return anArray;
412 }
413
414 //=================================================================================
415 // function : SetListOfIds
416 // purpose  : Called to set the list of SubShapes IDs
417 //=================================================================================
418 void StdMeshersGUI_SubShapeSelectorWdg::SetListOfIDs( SMESH::long_array_var theIds)
419 {
420   mySelectedIDs.clear();
421   myListOfIDs.clear();
422   int size = theIds->length();
423   for ( int i = 0; i < size; i++ )
424     mySelectedIDs.append( theIds[ i ] );
425   onAdd();
426 }
427