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