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