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