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