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