Salome HOME
Merge with OCC_development_01
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_ClippingDlg.cxx
1 //  SMESH SMESHGUI : GUI for SMESH component
2 //
3 //  Copyright (C) 2003  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SMESHGUI_ClippingDlg.cxx
25 //  Author : Nicolas REJNERI
26 //  Module : SMESH
27 //  $Header$
28
29 #include "SMESHGUI_ClippingDlg.h"
30
31 #include "SMESHGUI.h"
32 #include "SMESHGUI_Utils.h"
33 #include "SMESHGUI_VTKUtils.h"
34
35 #include <algorithm>
36
37 // QT Includes
38 #include <qlabel.h>
39 #include <qpushbutton.h>
40 #include <qcombobox.h>
41 #include <qcheckbox.h>
42 #include <qlayout.h>
43 #include <qgroupbox.h>
44
45 #include <vtkMath.h>
46 #include <vtkCamera.h>
47 #include <vtkRenderer.h>
48 #include <vtkImplicitBoolean.h>
49 #include <vtkImplicitFunctionCollection.h>
50 #include <vtkObjectFactory.h>
51
52 #include <vtkDataSet.h>
53 #include <vtkDataSetMapper.h>
54 #include <vtkPlaneSource.h>
55 #include <vtkPolyData.h>
56
57 #include "VTKViewer_ViewFrame.h"
58 #include "QAD_RightFrame.h"
59 #include "QAD_WaitCursor.h"
60 #include "SALOME_ListIteratorOfListIO.hxx"
61 #include "SMESH_Actor.h"
62 #include "SALOME_Selection.h"
63 #include "SALOME_InteractiveObject.hxx"
64 #include "SMESH_ActorUtils.h"
65
66 #include "VTKViewer_ViewFrame.h"
67 #include "VTKViewer_RenderWindow.h"
68
69 #include <vtkRenderer.h>
70
71 using namespace std;
72
73
74 class OrientedPlane: public vtkPlane
75 {
76   QAD_Study* myStudy;
77   QAD_StudyFrame* myStudyFrame;
78   VTKViewer_ViewFrame* myViewFrame;
79   
80   vtkDataSetMapper* myMapper;
81
82
83 public:
84   static OrientedPlane *New(){
85     return new OrientedPlane();
86   }
87   static OrientedPlane *New(QAD_Study* theStudy){
88     return new OrientedPlane(theStudy);
89   }
90   vtkTypeMacro(OrientedPlane, vtkPlane);
91   
92   
93   SMESH::Orientation myOrientation;
94   float myDistance;
95   double myAngle[2];
96
97   vtkPlaneSource* myPlaneSource;
98   SALOME_Actor *myActor;
99   
100   void SetOrientation(SMESH::Orientation theOrientation) {myOrientation = theOrientation;}
101   SMESH::Orientation GetOrientation() {return myOrientation;}
102
103   void SetDistance(float theDistance) {myDistance = theDistance;}
104   float GetDistance() {return myDistance;}
105
106   void ShallowCopy(OrientedPlane* theOrientedPlane){
107     SetNormal(theOrientedPlane->GetNormal());
108     SetOrigin(theOrientedPlane->GetOrigin());
109
110     myOrientation = theOrientedPlane->GetOrientation();
111     myDistance = theOrientedPlane->GetDistance();
112
113     myAngle[0] = theOrientedPlane->myAngle[0];
114     myAngle[1] = theOrientedPlane->myAngle[1];
115
116     myPlaneSource->SetNormal(theOrientedPlane->myPlaneSource->GetNormal());
117     myPlaneSource->SetOrigin(theOrientedPlane->myPlaneSource->GetOrigin());
118     myPlaneSource->SetPoint1(theOrientedPlane->myPlaneSource->GetPoint1());
119     myPlaneSource->SetPoint2(theOrientedPlane->myPlaneSource->GetPoint2());
120   }
121
122 protected:
123   OrientedPlane(QAD_Study* theStudy):
124     myOrientation(SMESH::XY),
125     myDistance(0.5),
126     myStudy(theStudy),
127     myStudyFrame(theStudy->getActiveStudyFrame()),
128     myViewFrame(SMESH::GetVtkViewFrame(theStudy->getActiveStudyFrame()))
129   {
130     Init();
131     myViewFrame->AddActor( myActor );
132   }
133
134   OrientedPlane():
135     myOrientation(SMESH::XY),
136     myDistance(0.5),
137     myStudy(NULL),
138     myStudyFrame(NULL),
139     myViewFrame(NULL)
140   {
141     Init();
142   }
143
144   void Init(){
145     myPlaneSource = vtkPlaneSource::New();
146
147     myAngle[0] = myAngle[1] = 0.0;
148
149     // Create and display actor
150     myMapper = vtkDataSetMapper::New();
151     myMapper->SetInput( myPlaneSource->GetOutput() );
152     
153     myActor = SALOME_Actor::New();
154     myActor->VisibilityOff();
155     myActor->PickableOff();
156     myActor->SetInfinitive(true);
157     myActor->SetMapper( myMapper );
158
159     vtkProperty* aProp = vtkProperty::New();
160     float anRGB[3];
161     anRGB[0] = SMESH::GetFloat("SMESH:SettingsFillColorRed", 0)/255.;
162     anRGB[1] = SMESH::GetFloat("SMESH:SettingsFillColorGreen", 170)/255.;
163     anRGB[2] = SMESH::GetFloat("SMESH:SettingsFillColorBlue", 255)/255.;
164     aProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
165     aProp->SetOpacity(0.75);
166     myActor->SetProperty( aProp );
167     aProp->Delete();
168     
169     vtkProperty* aBackProp = vtkProperty::New();
170     anRGB[0] = SMESH::GetFloat("SMESH:SettingsBackFaceColorRed", 0)/255.;
171     anRGB[1] = SMESH::GetFloat("SMESH:SettingsBackFaceColorGreen", 0)/255.;
172     anRGB[2] = SMESH::GetFloat("SMESH:SettingsBackFaceColorBlue", 255)/255.;
173     aBackProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
174     aBackProp->SetOpacity(0.75);
175     myActor->SetBackfaceProperty( aBackProp );
176     aBackProp->Delete();
177   }
178
179   ~OrientedPlane(){
180     if(myStudy && SMESH::FindVtkViewFrame(myStudy,myStudyFrame)){
181       myViewFrame->RemoveActor(myActor);
182     }
183     myActor->Delete();
184     
185     myMapper->RemoveAllInputs();
186     myMapper->Delete();
187     
188     myPlaneSource->UnRegisterAllOutputs();
189     myPlaneSource->Delete();
190   };
191   
192 private:
193   // Not implemented.
194   OrientedPlane(const OrientedPlane&); 
195   void operator=(const OrientedPlane&);
196
197 };
198
199 struct TSetVisiblity{
200   TSetVisiblity(int theIsVisible): myIsVisible(theIsVisible){}
201   void operator()(SMESH::TVTKPlane& theOrientedPlane){
202     theOrientedPlane->myActor->SetVisibility(myIsVisible);
203   }
204   int myIsVisible;
205 };
206
207
208 //=================================================================================
209 // class    : SMESHGUI_ClippingDlg()
210 // purpose  : 
211 //
212 //=================================================================================
213 SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( QWidget* parent,
214                                             const char* name,
215                                             bool modal,
216                                             WFlags fl )
217   : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose )
218 {
219   if ( !name )
220     setName( "SMESHGUI_ClippingDlg" );
221   setCaption( tr( "SMESH_CLIPPING_TITLE"  ) );
222   setSizeGripEnabled( TRUE );
223   QGridLayout* SMESHGUI_ClippingDlgLayout = new QGridLayout( this ); 
224   SMESHGUI_ClippingDlgLayout->setSpacing( 6 );
225   SMESHGUI_ClippingDlgLayout->setMargin( 11 );
226
227   // Controls for selecting, creating, deleting planes
228   QGroupBox* GroupPlanes = new QGroupBox( this, "GroupPlanes" );
229   GroupPlanes->setTitle( tr("Clipping planes") );
230   GroupPlanes->setColumnLayout(0, Qt::Vertical);
231   GroupPlanes->layout()->setSpacing( 0 );
232   GroupPlanes->layout()->setMargin( 0 );
233   QGridLayout* GroupPlanesLayout = new QGridLayout( GroupPlanes->layout() );
234   GroupPlanesLayout->setAlignment( Qt::AlignTop );
235   GroupPlanesLayout->setSpacing( 6 );
236   GroupPlanesLayout->setMargin( 11 );
237   
238   ComboBoxPlanes = new QComboBox(GroupPlanes, "ComboBoxPlanes");
239   GroupPlanesLayout->addWidget( ComboBoxPlanes, 0, 0 );
240   
241   QSpacerItem* spacerGP = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
242   GroupPlanesLayout->addItem( spacerGP, 0, 1 );
243   
244   buttonNew = new QPushButton( GroupPlanes, "buttonNew" );
245   buttonNew->setText( tr( "SMESH_BUT_NEW"  ) );
246   GroupPlanesLayout->addWidget( buttonNew, 0, 2 );
247   
248   buttonDelete = new QPushButton( GroupPlanes, "buttonDelete" );
249   buttonDelete->setText( tr( "SMESH_BUT_DELETE"  ) );
250   GroupPlanesLayout->addWidget( buttonDelete, 0, 3 );
251
252   // Controls for defining plane parameters
253   QGroupBox* GroupParameters = new QGroupBox( this, "GroupParameters" );
254   GroupParameters->setTitle( tr("SMESH_PARAMETERS") );
255   GroupParameters->setColumnLayout(0, Qt::Vertical);
256   GroupParameters->layout()->setSpacing( 0 );
257   GroupParameters->layout()->setMargin( 0 );
258   QGridLayout* GroupParametersLayout = new QGridLayout( GroupParameters->layout() );
259   GroupParametersLayout->setAlignment( Qt::AlignTop );
260   GroupParametersLayout->setSpacing( 6 );
261   GroupParametersLayout->setMargin( 11 );
262   
263   TextLabelOrientation = new QLabel( GroupParameters, "TextLabelOrientation" );
264   TextLabelOrientation->setText( tr("SMESH_ORIENTATION") );
265   GroupParametersLayout->addWidget( TextLabelOrientation, 0, 0 );
266   
267   ComboBoxOrientation = new QComboBox(GroupParameters, "ComboBoxOrientation");
268   GroupParametersLayout->addWidget( ComboBoxOrientation, 0, 1 );
269   
270   TextLabelDistance = new QLabel( GroupParameters, "TextLabelDistance" );
271   TextLabelDistance->setText( tr("SMESH_DISTANCE") );
272   GroupParametersLayout->addWidget( TextLabelDistance, 1, 0 );
273
274   SpinBoxDistance = new SMESHGUI_SpinBox( GroupParameters, "SpinBoxDistance" );
275   GroupParametersLayout->addWidget( SpinBoxDistance, 1, 1 );
276
277   TextLabelRot1 = new QLabel( GroupParameters, "TextLabelRot1" );
278   TextLabelRot1->setText( tr("Rotation around X (Y to Z):") );
279   GroupParametersLayout->addWidget( TextLabelRot1, 2, 0 );
280
281   SpinBoxRot1 = new SMESHGUI_SpinBox( GroupParameters, "SpinBoxRot1" );
282   GroupParametersLayout->addWidget( SpinBoxRot1, 2, 1 );
283  
284   TextLabelRot2 = new QLabel( GroupParameters, "TextLabelRot2" );
285   TextLabelRot2->setText( tr("Rotation around Y (X to Z):") );
286   GroupParametersLayout->addWidget( TextLabelRot2, 3, 0 );
287   
288   SpinBoxRot2 = new SMESHGUI_SpinBox( GroupParameters, "SpinBoxRot2" );
289   GroupParametersLayout->addWidget( SpinBoxRot2, 3, 1 );
290
291   PreviewCheckBox = new QCheckBox(tr("Show preview"), GroupParameters);
292   PreviewCheckBox->setChecked(true);
293   GroupParametersLayout->addWidget( PreviewCheckBox, 4, 0 );
294
295   AutoApplyCheckBox = new QCheckBox(tr("Auto Apply"), GroupParameters);
296   AutoApplyCheckBox->setChecked(false);
297   GroupParametersLayout->addWidget( AutoApplyCheckBox, 4, 1 );
298    
299   // Controls for "Ok", "Apply" and "Close" button
300   QGroupBox* GroupButtons = new QGroupBox( this, "GroupButtons" );
301   GroupButtons->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)7, (QSizePolicy::SizeType)0, 0, 0, GroupButtons->sizePolicy().hasHeightForWidth() ) );
302   GroupButtons->setGeometry( QRect( 10, 10, 281, 48 ) ); 
303   GroupButtons->setTitle( tr( ""  ) );
304   GroupButtons->setColumnLayout(0, Qt::Vertical );
305   GroupButtons->layout()->setSpacing( 0 );
306   GroupButtons->layout()->setMargin( 0 );
307   QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() );
308   GroupButtonsLayout->setAlignment( Qt::AlignTop );
309   GroupButtonsLayout->setSpacing( 6 );
310   GroupButtonsLayout->setMargin( 11 );
311   buttonCancel = new QPushButton( GroupButtons, "buttonCancel" );
312   buttonCancel->setText( tr( "SMESH_BUT_CLOSE"  ) );
313   buttonCancel->setAutoDefault( TRUE );
314   GroupButtonsLayout->addWidget( buttonCancel, 0, 3 );
315   buttonApply = new QPushButton( GroupButtons, "buttonApply" );
316   buttonApply->setText( tr( "SMESH_BUT_APPLY"  ) );
317   buttonApply->setAutoDefault( TRUE );
318   GroupButtonsLayout->addWidget( buttonApply, 0, 1 );
319   QSpacerItem* spacer_9 = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
320   GroupButtonsLayout->addItem( spacer_9, 0, 2 );
321   buttonOk = new QPushButton( GroupButtons, "buttonOk" );
322   buttonOk->setText( tr( "SMESH_BUT_OK"  ) );
323   buttonOk->setAutoDefault( TRUE );
324   buttonOk->setDefault( TRUE );
325   GroupButtonsLayout->addWidget( buttonOk, 0, 0 );
326
327   SMESHGUI_ClippingDlgLayout->addWidget( GroupPlanes,      0, 0 );
328   SMESHGUI_ClippingDlgLayout->addWidget( GroupParameters,  1, 0 );
329   SMESHGUI_ClippingDlgLayout->addWidget( GroupButtons,     2, 0 );
330   
331   mySelection = SALOME_Selection::Selection( SMESHGUI::GetSMESHGUI()->GetActiveStudy()->getSelection());
332
333   // Initial state
334   SpinBoxDistance->RangeStepAndValidator( 0.0, 1.0, 0.01, 3 );
335   SpinBoxRot1->RangeStepAndValidator( -180.0, 180.0, 1, 3 );
336   SpinBoxRot2->RangeStepAndValidator( -180.0, 180.0, 1, 3 );
337
338   ComboBoxOrientation->insertItem( tr("|| X-Y") );
339   ComboBoxOrientation->insertItem( tr("|| Y-Z") );
340   ComboBoxOrientation->insertItem( tr("|| Z-X") );
341
342   SpinBoxDistance->SetValue(0.5);
343
344   myActor = 0;
345   myIsSelectPlane = false;
346   onSelectionChanged();
347   
348   // signals and slots connections :
349   connect( ComboBoxPlanes, SIGNAL( activated( int )), this, SLOT( onSelectPlane( int ) ) );
350   connect( buttonNew, SIGNAL( clicked() ), this, SLOT( ClickOnNew() ) );
351   connect( buttonDelete, SIGNAL( clicked() ), this, SLOT( ClickOnDelete() ) );
352   connect( ComboBoxOrientation, SIGNAL( activated( int )), this, SLOT( onSelectOrientation( int ) ) );
353   connect( SpinBoxDistance, SIGNAL( valueChanged( double )), this, SLOT( SetCurrentPlaneParam() ) );
354   connect( SpinBoxRot1, SIGNAL( valueChanged( double )), this, SLOT( SetCurrentPlaneParam() ) );
355   connect( SpinBoxRot2, SIGNAL( valueChanged( double )), this, SLOT( SetCurrentPlaneParam() ) );
356   connect( PreviewCheckBox, SIGNAL( toggled( bool )), this, SLOT( OnPreviewToggle( bool ) ) );
357   connect( AutoApplyCheckBox, SIGNAL( toggled( bool )), this, SLOT( ClickOnApply() ) );
358   connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
359   connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( ClickOnCancel() ) ) ;
360   connect( buttonApply, SIGNAL( clicked() ), this, SLOT(ClickOnApply() ) );
361   connect( SMESHGUI::GetSMESHGUI(), SIGNAL ( SignalCloseAllDialogs() ), this, SLOT( ClickOnOk() ) ) ;
362   connect( mySelection,  SIGNAL( currentSelectionChanged() ), this, SLOT( onSelectionChanged() ) );
363   /* to close dialog if study frame change */
364   connect( SMESHGUI::GetSMESHGUI(), SIGNAL ( SignalStudyFrameChanged() ),  this, SLOT( ClickOnCancel() ) ) ;
365   
366   /* Move widget on the botton right corner of main widget */
367   int x, y ;
368   SMESHGUI::GetSMESHGUI()->DefineDlgPosition( this, x, y ) ;
369   this->move( x, y ) ;
370   this->show();
371 }
372
373
374 //=================================================================================
375 // function : ~SMESHGUI_ClippingDlg()
376 // purpose  :
377 //=================================================================================
378 SMESHGUI_ClippingDlg::~SMESHGUI_ClippingDlg()
379 {
380   // no need to delete child widgets, Qt does it all for us
381   std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
382   SMESH::RenderViewFrame(SMESH::GetCurrentVtkView());
383 }
384
385
386 //=======================================================================
387 // function : ClickOnApply()
388 // purpose  :
389 //=======================================================================
390 void SMESHGUI_ClippingDlg::ClickOnApply()
391 {
392   if (!myActor)
393     return;
394
395   if ( SMESHGUI::GetSMESHGUI()->GetActiveStudy()->getActiveStudyFrame()->getTypeView() == VIEW_VTK ) {
396     QAD_WaitCursor wc;
397     
398     vtkImplicitBoolean* aBoolean = myActor->GetPlaneContainer();
399     vtkImplicitFunctionCollection* aCollection = aBoolean->GetFunction();
400     aCollection->RemoveAllItems();
401     aBoolean->Modified(); // VTK bug
402     aCollection->InitTraversal();
403     
404     SMESH::TPlanes::iterator anIter = myPlanes.begin();
405     for (;anIter != myPlanes.end();anIter++){
406       OrientedPlane* anOrientedPlane = OrientedPlane::New();
407       anOrientedPlane->ShallowCopy(anIter->GetPointer());
408       aCollection->AddItem(anOrientedPlane);
409       anOrientedPlane->Delete();
410     }
411
412     SMESH::RenderViewFrame(SMESH::GetCurrentVtkView());
413   }
414 }
415
416
417 //=======================================================================
418 // function : ClickOnOk()
419 // purpose  :
420 //=======================================================================
421 void SMESHGUI_ClippingDlg::ClickOnOk()
422 {
423   ClickOnApply() ;
424   ClickOnCancel() ;
425 }
426
427
428 //=======================================================================
429 // function : ClickOnCancel()
430 // purpose  :
431 //=======================================================================
432 void SMESHGUI_ClippingDlg::ClickOnCancel()
433 {
434   close();
435 }
436
437
438 //=================================================================================
439 // function : onSelectionChanged()
440 // purpose  : Called when selection is changed
441 //=================================================================================
442 void SMESHGUI_ClippingDlg::onSelectionChanged()
443 {
444   if ( SMESHGUI::GetSMESHGUI()->GetActiveStudy()->getActiveStudyFrame()->getTypeView() == VIEW_VTK ) {
445     if ( mySelection->IObjectCount() ) {
446       Handle(SALOME_InteractiveObject) IOS = mySelection->firstIObject();
447       myActor = SMESH::FindActorByEntry(IOS->getEntry());
448       if ( myActor ){
449         vtkImplicitBoolean* aBoolean = myActor->GetPlaneContainer();
450         vtkImplicitFunctionCollection* aCollection = aBoolean->GetFunction();
451         aCollection->InitTraversal();
452         std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
453         myPlanes.clear();
454         while(vtkImplicitFunction* aFunction = aCollection->GetNextItem()){
455           if(OrientedPlane* aPlane = OrientedPlane::SafeDownCast(aFunction)){
456             OrientedPlane* anOrientedPlane = OrientedPlane::New(SMESH::GetActiveStudy());
457             SMESH::TVTKPlane aTVTKPlane(anOrientedPlane);
458             anOrientedPlane->Delete();
459             aTVTKPlane->ShallowCopy(aPlane);
460             myPlanes.push_back(aTVTKPlane);
461           }
462         }
463         std::for_each(myPlanes.begin(),myPlanes.end(),
464                       TSetVisiblity(PreviewCheckBox->isChecked()));
465       }
466     }
467   }
468   Sinchronize();
469   SMESH::RenderViewFrame(SMESH::GetCurrentVtkView());
470 }
471
472
473 //=======================================================================
474 // function : onSelectPlane()
475 // purpose  :
476 //=======================================================================
477 void SMESHGUI_ClippingDlg::onSelectPlane(int theIndex)
478 {  
479   if (!myActor || myPlanes.empty())
480     return;
481   
482   OrientedPlane* aPlane = myPlanes[theIndex].GetPointer();
483   
484   // Orientation
485   SMESH::Orientation anOrientation = aPlane->GetOrientation();
486   
487   // Rotations
488   double aRot[2] = {aPlane->myAngle[0], aPlane->myAngle[1]};
489
490   // Set plane parameters in the dialog
491   myIsSelectPlane = true;
492   setDistance(aPlane->GetDistance());
493   setRotation(aRot[0], aRot[1]);
494   switch (anOrientation) {
495   case SMESH::XY: 
496     ComboBoxOrientation->setCurrentItem(0);
497     onSelectOrientation(0);
498     break;
499   case SMESH::YZ: 
500     ComboBoxOrientation->setCurrentItem(1);
501     onSelectOrientation(1);
502     break;
503   case SMESH::ZX: 
504     ComboBoxOrientation->setCurrentItem(2);
505     onSelectOrientation(2);
506     break;
507   }
508   myIsSelectPlane = false;
509 }
510
511
512 //=======================================================================
513 // function : ClickOnNew()
514 // purpose  :
515 //=======================================================================
516 void SMESHGUI_ClippingDlg::ClickOnNew()
517 {
518   if (!myActor)
519     return;
520   
521   OrientedPlane* aPlane = OrientedPlane::New(SMESH::GetActiveStudy());
522   SMESH::TVTKPlane aTVTKPlane(aPlane);
523   myPlanes.push_back(aTVTKPlane);
524
525   if(PreviewCheckBox->isChecked())
526     aTVTKPlane->myActor->VisibilityOn();
527
528   Sinchronize();
529   SetCurrentPlaneParam();
530 }
531
532
533 //=======================================================================
534 // function : ClickOnDelete()
535 // purpose  :
536 //=======================================================================
537 void SMESHGUI_ClippingDlg::ClickOnDelete()
538 {
539   if (!myActor || myPlanes.empty())
540     return;
541   
542   int aPlaneIndex = ComboBoxPlanes->currentItem();
543   
544   SMESH::TPlanes::iterator anIter = myPlanes.begin() + aPlaneIndex;
545   anIter->GetPointer()->myActor->SetVisibility(false);
546   myPlanes.erase(anIter);
547   
548   if(AutoApplyCheckBox->isChecked())
549     ClickOnApply();
550
551   Sinchronize();
552   SMESH::RenderViewFrame(SMESH::GetCurrentVtkView());
553 }
554
555
556 //=======================================================================
557 // function : onSelectOrientation()
558 // purpose  :
559 //=======================================================================
560 void SMESHGUI_ClippingDlg::onSelectOrientation(int theItem)
561 {
562   if (myPlanes.empty())
563     return;
564   
565   if      (theItem == 0) {
566     TextLabelRot1->setText( tr( "Rotation around X (Y to Z):") );
567     TextLabelRot2->setText( tr( "Rotation around Y (X to Z):" ) );
568   }
569   else if (theItem == 1) {
570     TextLabelRot1->setText( tr( "Rotation around Y (Z to X):" ) );
571     TextLabelRot2->setText( tr( "Rotation around Z (Y to X):" ) );
572   }
573   else if (theItem == 2) {
574     TextLabelRot1->setText( tr( "Rotation around Z (X to Y):" ) );
575     TextLabelRot2->setText( tr( "Rotation around X (Z to Y):" ) );
576   }
577   
578   if((QComboBox*)sender() == ComboBoxOrientation)
579     SetCurrentPlaneParam();
580 }
581
582
583 //=======================================================================
584 // function : Sinchronize()
585 // purpose  :
586 //=======================================================================
587 void SMESHGUI_ClippingDlg::Sinchronize()
588 {
589   int aNbPlanes = myPlanes.size();
590   ComboBoxPlanes->clear();
591   
592   QString aName;
593   for(int i = 1; i<=aNbPlanes ; i++){
594     aName = QString(tr("Plane# %1")).arg(i);
595     ComboBoxPlanes->insertItem(aName);
596   }
597   
598   int aPos = ComboBoxPlanes->count() - 1;
599   ComboBoxPlanes->setCurrentItem(aPos);
600   
601   bool anIsControlsEnable = (aPos >= 0);
602   if(anIsControlsEnable){
603     onSelectPlane(aPos);
604   }else{
605     ComboBoxPlanes->insertItem( tr("No planes") );
606     SpinBoxRot1->SetValue(0.0);
607     SpinBoxRot2->SetValue(0.0);
608     SpinBoxDistance->SetValue(0.5);
609   }
610
611   buttonDelete->setEnabled(anIsControlsEnable);
612   buttonApply->setEnabled(anIsControlsEnable);
613   PreviewCheckBox->setEnabled(anIsControlsEnable);
614   AutoApplyCheckBox->setEnabled(anIsControlsEnable);
615   ComboBoxOrientation->setEnabled(anIsControlsEnable);
616   SpinBoxDistance->setEnabled(anIsControlsEnable);
617   SpinBoxRot1->setEnabled(anIsControlsEnable);
618   SpinBoxRot2->setEnabled(anIsControlsEnable);
619 }
620
621
622 //=======================================================================
623 // function : setRotation()
624 // purpose  :
625 //=======================================================================
626 void SMESHGUI_ClippingDlg::setRotation( const double theRot1, const double theRot2 )
627 {
628   SpinBoxRot1->SetValue(theRot1);
629   SpinBoxRot2->SetValue(theRot2);
630 }
631
632
633 //=======================================================================
634 // function : SetCurrentPlaneParam
635 // purpose  :
636 //=======================================================================
637 void SMESHGUI_ClippingDlg::SetCurrentPlaneParam()
638 {
639   if(myPlanes.empty() || myIsSelectPlane)
640     return;
641   
642   int aCurPlaneIndex = ComboBoxPlanes->currentItem();
643   
644   OrientedPlane* aPlane = myPlanes[aCurPlaneIndex].GetPointer();
645   
646   float aNormal[3];
647   SMESH::Orientation anOrientation;
648   float aDir[3][3] = {{0, 0, 0}, {0, 0, 0}};
649   {  
650     static double aCoeff = vtkMath::Pi()/180.0;
651
652     float aRot[2] = {getRotation1(), getRotation2()};
653     aPlane->myAngle[0] = aRot[0];
654     aPlane->myAngle[1] = aRot[1];
655
656     float anU[2] = {cos(aCoeff*aRot[0]), cos(aCoeff*aRot[1])};
657     float aV[2] = {sqrt(1.0-anU[0]*anU[0]), sqrt(1.0-anU[1]*anU[1])};
658     aV[0] = aRot[0] > 0? aV[0]: -aV[0];
659     aV[1] = aRot[1] > 0? aV[1]: -aV[1];
660                     
661     switch (ComboBoxOrientation->currentItem()) {
662     case 0: 
663       anOrientation = SMESH::XY; 
664
665       aDir[0][1] = anU[0];
666       aDir[0][2] = aV[0];
667
668       aDir[1][0] = anU[1];
669       aDir[1][2] = aV[1];
670
671       break;
672     case 1: 
673       anOrientation = SMESH::YZ; 
674
675       aDir[0][2] = anU[0];
676       aDir[0][0] = aV[0];
677
678       aDir[1][1] = anU[1];
679       aDir[1][0] = aV[1];
680
681       break;
682     case 2: 
683       anOrientation = SMESH::ZX; 
684
685       aDir[0][0] = anU[0];
686       aDir[0][1] = aV[0];
687
688       aDir[1][2] = anU[1];
689       aDir[1][1] = aV[1];
690
691       break;
692     }
693
694     vtkMath::Cross(aDir[1],aDir[0],aNormal);
695     vtkMath::Normalize(aNormal);
696     vtkMath::Cross(aNormal,aDir[1],aDir[0]);
697   }
698   
699   aPlane->SetOrientation(anOrientation);
700   aPlane->SetDistance(getDistance());
701   
702   myActor->SetPlaneParam(aNormal, getDistance(), aPlane);
703
704   vtkDataSet* aDataSet = myActor->GetInput();
705   float *aPnt = aDataSet->GetCenter();
706
707   float* anOrigin = aPlane->GetOrigin();
708   float aDel = aDataSet->GetLength()/2.0;
709
710   float aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel},
711                         {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}};
712   float aParam, aPnt0[3], aPnt1[3], aPnt2[3];
713
714   float aPnt01[3] = {aPnt[0] - aDelta[0][0] - aDelta[1][0], 
715                      aPnt[1] - aDelta[0][1] - aDelta[1][1], 
716                      aPnt[2] - aDelta[0][2] - aDelta[1][2]};
717   float aPnt02[3] = {aPnt01[0] + aNormal[0], 
718                       aPnt01[1] + aNormal[1], 
719                       aPnt01[2] + aNormal[2]};
720   vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0);
721
722   float aPnt11[3] = {aPnt[0] - aDelta[0][0] + aDelta[1][0], 
723                      aPnt[1] - aDelta[0][1] + aDelta[1][1], 
724                      aPnt[2] - aDelta[0][2] + aDelta[1][2]};
725   float aPnt12[3] = {aPnt11[0] + aNormal[0], 
726                      aPnt11[1] + aNormal[1], 
727                      aPnt11[2] + aNormal[2]};
728   vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1);
729   
730   float aPnt21[3] = {aPnt[0] + aDelta[0][0] - aDelta[1][0], 
731                      aPnt[1] + aDelta[0][1] - aDelta[1][1], 
732                      aPnt[2] + aDelta[0][2] - aDelta[1][2]};
733   float aPnt22[3] = {aPnt21[0] + aNormal[0], 
734                      aPnt21[1] + aNormal[1], 
735                      aPnt21[2] + aNormal[2]};
736   vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2);
737   
738   vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource;
739   aPlaneSource->SetNormal(aNormal[0],aNormal[1],aNormal[2]);
740   aPlaneSource->SetOrigin(aPnt0[0],aPnt0[1],aPnt0[2]);
741   aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]);
742   aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]);
743   
744   if(AutoApplyCheckBox->isChecked())
745     ClickOnApply();
746   
747   SMESH::RenderViewFrame(SMESH::GetCurrentVtkView());
748 }
749
750
751 void SMESHGUI_ClippingDlg::OnPreviewToggle(bool theIsToggled){
752   std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(theIsToggled));
753   SMESH::RenderViewFrame(SMESH::GetCurrentVtkView());
754 }