Salome HOME
PAL15429 Computation of the mesh, based on "014.brep" via Tetrahedron(NETGEN), is...
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_ClippingDlg.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  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 //  SMESH SMESHGUI : GUI for SMESH component
23 //  File   : SMESHGUI_ClippingDlg.cxx
24 //  Author : Nicolas REJNERI
25 //  Module : SMESH
26 //  $Header$
27
28 #include "SMESHGUI_ClippingDlg.h"
29
30 #include "SMESHGUI.h"
31 #include "SMESHGUI_Utils.h"
32 #include "SMESHGUI_VTKUtils.h"
33
34 #include "SMESH_Actor.h"
35 #include "SMESH_ActorUtils.h"
36
37 #include "SUIT_Session.h"
38 #include "SUIT_OverrideCursor.h"
39 #include "SUIT_MessageBox.h"
40
41 #include "SALOME_ListIO.hxx"
42 #include "SALOME_InteractiveObject.hxx"
43 #include "SALOME_ListIteratorOfListIO.hxx"
44
45 #include "LightApp_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     vtkFloatingPointType 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     // commented: porting to vtk 5.0
185     //    myPlaneSource->UnRegisterAllOutputs();
186     myPlaneSource->Delete();
187   };
188
189 private:
190   // Not implemented.
191   OrientedPlane (const OrientedPlane&);
192   void operator= (const OrientedPlane&);
193
194 };
195
196 struct TSetVisiblity {
197   TSetVisiblity(int theIsVisible): myIsVisible(theIsVisible){}
198   void operator()(SMESH::TVTKPlane& theOrientedPlane){
199     theOrientedPlane->myActor->SetVisibility(myIsVisible);
200   }
201   int myIsVisible;
202 };
203
204 //=================================================================================
205 // class    : SMESHGUI_ClippingDlg()
206 // purpose  :
207 //
208 //=================================================================================
209 SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg (SMESHGUI* theModule,
210                                             const char* name,
211                                             bool modal,
212                                             WFlags fl):
213   QDialog(SMESH::GetDesktop(theModule),
214           name, 
215           modal, 
216           WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
217   mySelector(SMESH::GetViewWindow(theModule)->GetSelector()),
218   mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
219   mySMESHGUI(theModule)
220 {
221   if (!name)
222     setName("SMESHGUI_ClippingDlg");
223   setCaption(tr("SMESH_CLIPPING_TITLE"));
224   setSizeGripEnabled(TRUE);
225   QGridLayout* SMESHGUI_ClippingDlgLayout = new QGridLayout(this);
226   SMESHGUI_ClippingDlgLayout->setSpacing(6);
227   SMESHGUI_ClippingDlgLayout->setMargin(11);
228
229   // Controls for selecting, creating, deleting planes
230   QGroupBox* GroupPlanes = new QGroupBox (this, "GroupPlanes");
231   GroupPlanes->setTitle(tr("Clipping planes"));
232   GroupPlanes->setColumnLayout(0, Qt::Vertical);
233   GroupPlanes->layout()->setSpacing(0);
234   GroupPlanes->layout()->setMargin(0);
235   QGridLayout* GroupPlanesLayout = new QGridLayout (GroupPlanes->layout());
236   GroupPlanesLayout->setAlignment(Qt::AlignTop);
237   GroupPlanesLayout->setSpacing(6);
238   GroupPlanesLayout->setMargin(11);
239
240   ComboBoxPlanes = new QComboBox(GroupPlanes, "ComboBoxPlanes");
241   GroupPlanesLayout->addWidget(ComboBoxPlanes, 0, 0);
242
243   QSpacerItem* spacerGP = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
244   GroupPlanesLayout->addItem(spacerGP, 0, 1);
245
246   buttonNew = new QPushButton (GroupPlanes, "buttonNew");
247   buttonNew->setText(tr("SMESH_BUT_NEW"));
248   GroupPlanesLayout->addWidget(buttonNew, 0, 2);
249
250   buttonDelete = new QPushButton (GroupPlanes, "buttonDelete");
251   buttonDelete->setText(tr("SMESH_BUT_DELETE"));
252   GroupPlanesLayout->addWidget(buttonDelete, 0, 3);
253
254   // Controls for defining plane parameters
255   QGroupBox* GroupParameters = new QGroupBox (this, "GroupParameters");
256   GroupParameters->setTitle(tr("SMESH_PARAMETERS"));
257   GroupParameters->setColumnLayout(0, Qt::Vertical);
258   GroupParameters->layout()->setSpacing(0);
259   GroupParameters->layout()->setMargin(0);
260   QGridLayout* GroupParametersLayout = new QGridLayout (GroupParameters->layout());
261   GroupParametersLayout->setAlignment(Qt::AlignTop);
262   GroupParametersLayout->setSpacing(6);
263   GroupParametersLayout->setMargin(11);
264
265   TextLabelOrientation = new QLabel(GroupParameters, "TextLabelOrientation");
266   TextLabelOrientation->setText(tr("SMESH_ORIENTATION"));
267   GroupParametersLayout->addWidget(TextLabelOrientation, 0, 0);
268
269   ComboBoxOrientation = new QComboBox(GroupParameters, "ComboBoxOrientation");
270   GroupParametersLayout->addWidget(ComboBoxOrientation, 0, 1);
271
272   TextLabelDistance = new QLabel(GroupParameters, "TextLabelDistance");
273   TextLabelDistance->setText(tr("SMESH_DISTANCE"));
274   GroupParametersLayout->addWidget(TextLabelDistance, 1, 0);
275
276   SpinBoxDistance = new SMESHGUI_SpinBox(GroupParameters, "SpinBoxDistance");
277   GroupParametersLayout->addWidget(SpinBoxDistance, 1, 1);
278
279   TextLabelRot1 = new QLabel(GroupParameters, "TextLabelRot1");
280   TextLabelRot1->setText(tr("Rotation around X (Y to Z):"));
281   GroupParametersLayout->addWidget(TextLabelRot1, 2, 0);
282
283   SpinBoxRot1 = new SMESHGUI_SpinBox(GroupParameters, "SpinBoxRot1");
284   GroupParametersLayout->addWidget(SpinBoxRot1, 2, 1);
285
286   TextLabelRot2 = new QLabel(GroupParameters, "TextLabelRot2");
287   TextLabelRot2->setText(tr("Rotation around Y (X to Z):"));
288   GroupParametersLayout->addWidget(TextLabelRot2, 3, 0);
289
290   SpinBoxRot2 = new SMESHGUI_SpinBox(GroupParameters, "SpinBoxRot2");
291   GroupParametersLayout->addWidget(SpinBoxRot2, 3, 1);
292
293   PreviewCheckBox = new QCheckBox(tr("Show preview"), GroupParameters);
294   PreviewCheckBox->setChecked(true);
295   GroupParametersLayout->addWidget(PreviewCheckBox, 4, 0);
296
297   AutoApplyCheckBox = new QCheckBox(tr("Auto Apply"), GroupParameters);
298   AutoApplyCheckBox->setChecked(false);
299   GroupParametersLayout->addWidget(AutoApplyCheckBox, 4, 1);
300
301   // Controls for "Ok", "Apply" and "Close" button
302   QGroupBox* GroupButtons = new QGroupBox(this, "GroupButtons");
303   GroupButtons->setSizePolicy(QSizePolicy((QSizePolicy::SizeType)7, (QSizePolicy::SizeType)0, 0, 0, GroupButtons->sizePolicy().hasHeightForWidth()));
304   GroupButtons->setGeometry(QRect(10, 10, 281, 48));
305   GroupButtons->setTitle(tr("" ));
306   GroupButtons->setColumnLayout(0, Qt::Vertical);
307   GroupButtons->layout()->setSpacing(0);
308   GroupButtons->layout()->setMargin(0);
309   QGridLayout* GroupButtonsLayout = new QGridLayout(GroupButtons->layout());
310   GroupButtonsLayout->setAlignment(Qt::AlignTop);
311   GroupButtonsLayout->setSpacing(6);
312   GroupButtonsLayout->setMargin(11);
313   buttonCancel = new QPushButton(GroupButtons, "buttonCancel");
314   buttonCancel->setText(tr("SMESH_BUT_CLOSE" ));
315   buttonCancel->setAutoDefault(TRUE);
316   GroupButtonsLayout->addWidget(buttonCancel, 0, 3);
317   buttonApply = new QPushButton(GroupButtons, "buttonApply");
318   buttonApply->setText(tr("SMESH_BUT_APPLY" ));
319   buttonApply->setAutoDefault(TRUE);
320   GroupButtonsLayout->addWidget(buttonApply, 0, 1);
321   QSpacerItem* spacer_9 = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
322   GroupButtonsLayout->addItem(spacer_9, 0, 2);
323   buttonOk = new QPushButton(GroupButtons, "buttonOk");
324   buttonOk->setText(tr("SMESH_BUT_APPLY_AND_CLOSE" ));
325   buttonOk->setAutoDefault(TRUE);
326   buttonOk->setDefault(TRUE);
327   GroupButtonsLayout->addWidget(buttonOk, 0, 0);
328   buttonHelp = new QPushButton(GroupButtons, "buttonHelp");
329   buttonHelp->setText(tr("SMESH_BUT_HELP" ));
330   buttonHelp->setAutoDefault(TRUE);
331   GroupButtonsLayout->addWidget(buttonHelp, 0, 4);
332
333   SMESHGUI_ClippingDlgLayout->addWidget(GroupPlanes,      0, 0);
334   SMESHGUI_ClippingDlgLayout->addWidget(GroupParameters,  1, 0);
335   SMESHGUI_ClippingDlgLayout->addWidget(GroupButtons,     2, 0);
336
337   // Initial state
338   SpinBoxDistance->RangeStepAndValidator(0.0, 1.0, 0.01, 3);
339   SpinBoxRot1->RangeStepAndValidator(-180.0, 180.0, 1, 3);
340   SpinBoxRot2->RangeStepAndValidator(-180.0, 180.0, 1, 3);
341
342   ComboBoxOrientation->insertItem(tr("|| X-Y"));
343   ComboBoxOrientation->insertItem(tr("|| Y-Z"));
344   ComboBoxOrientation->insertItem(tr("|| Z-X"));
345
346   SpinBoxDistance->SetValue(0.5);
347
348   myActor = 0;
349   myIsSelectPlane = false;
350   onSelectionChanged();
351
352   myHelpFileName = "clipping_page.html";
353
354   // signals and slots connections :
355   connect(ComboBoxPlanes, SIGNAL(activated(int)), this, SLOT(onSelectPlane(int)));
356   connect(buttonNew, SIGNAL(clicked()), this, SLOT(ClickOnNew()));
357   connect(buttonDelete, SIGNAL(clicked()), this, SLOT(ClickOnDelete()));
358   connect(ComboBoxOrientation, SIGNAL(activated(int)), this, SLOT(onSelectOrientation(int)));
359   connect(SpinBoxDistance, SIGNAL(valueChanged(double)), this, SLOT(SetCurrentPlaneParam()));
360   connect(SpinBoxRot1, SIGNAL(valueChanged(double)), this, SLOT(SetCurrentPlaneParam()));
361   connect(SpinBoxRot2, SIGNAL(valueChanged(double)), this, SLOT(SetCurrentPlaneParam()));
362   connect(PreviewCheckBox, SIGNAL(toggled(bool)), this, SLOT(OnPreviewToggle(bool)));
363   connect(AutoApplyCheckBox, SIGNAL(toggled(bool)), this, SLOT(ClickOnApply()));
364   connect(buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk()));
365   connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()));
366   connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply()));
367   connect(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
368   connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnCancel()));
369   connect(mySelectionMgr,  SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionChanged()));
370   /* to close dialog if study frame change */
371   connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), this, SLOT(ClickOnCancel()));
372
373   this->show();
374 }
375
376 //=================================================================================
377 // function : ~SMESHGUI_ClippingDlg()
378 // purpose  :
379 //=================================================================================
380 SMESHGUI_ClippingDlg::~SMESHGUI_ClippingDlg()
381 {
382   // no need to delete child widgets, Qt does it all for us
383   std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
384   if (mySMESHGUI)
385     if (SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(mySMESHGUI))
386       SMESH::RenderViewWindow(aViewWindow);
387 }
388
389 //=======================================================================
390 // function : ClickOnApply()
391 // purpose  :
392 //=======================================================================
393 void SMESHGUI_ClippingDlg::ClickOnApply()
394 {
395   if (!myActor)
396     return;
397
398   if (SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(mySMESHGUI)) {
399     SUIT_OverrideCursor wc;
400     
401     QWidget *aCurrWid = this->focusWidget();
402     aCurrWid->clearFocus();
403     aCurrWid->setFocus();
404
405     myActor->RemoveAllClippingPlanes();
406
407     SMESH::TPlanes::iterator anIter = myPlanes.begin();
408     for (; anIter != myPlanes.end(); anIter++) {
409       OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow);
410       anOrientedPlane->ShallowCopy(anIter->GetPointer());
411       myActor->AddClippingPlane(anOrientedPlane);
412       anOrientedPlane->Delete();
413     }
414
415     SMESH::RenderViewWindow(aViewWindow);
416   }
417 }
418
419 //=======================================================================
420 // function : ClickOnOk()
421 // purpose  :
422 //=======================================================================
423 void SMESHGUI_ClippingDlg::ClickOnOk()
424 {
425   ClickOnApply();
426   ClickOnCancel();
427 }
428
429 //=======================================================================
430 // function : ClickOnCancel()
431 // purpose  :
432 //=======================================================================
433 void SMESHGUI_ClippingDlg::ClickOnCancel()
434 {
435   close();
436 }
437
438 //=================================================================================
439 // function : ClickOnHelp()
440 // purpose  :
441 //=================================================================================
442 void SMESHGUI_ClippingDlg::ClickOnHelp()
443 {
444   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
445   if (app) 
446     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
447   else {
448                 QString platform;
449 #ifdef WIN32
450                 platform = "winapplication";
451 #else
452                 platform = "application";
453 #endif
454     SUIT_MessageBox::warn1(0, QObject::tr("WRN_WARNING"),
455                            QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
456                            arg(app->resourceMgr()->stringValue("ExternalBrowser", platform)).arg(myHelpFileName),
457                            QObject::tr("BUT_OK"));
458   }
459 }
460
461 //=================================================================================
462 // function : onSelectionChanged()
463 // purpose  : Called when selection is changed
464 //=================================================================================
465 void SMESHGUI_ClippingDlg::onSelectionChanged()
466 {
467   if (SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(mySMESHGUI)) {
468     const SALOME_ListIO& aList = mySelector->StoredIObjects();
469     if (aList.Extent() > 0) {
470       Handle(SALOME_InteractiveObject) IOS = aList.First();
471       myActor = SMESH::FindActorByEntry(IOS->getEntry());
472       if (myActor) {
473         std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
474         myPlanes.clear();
475
476         vtkIdType anId = 0, anEnd = myActor->GetNumberOfClippingPlanes();
477         for (; anId < anEnd; anId++) {
478           if (vtkImplicitFunction* aFunction = myActor->GetClippingPlane(anId)) {
479             if(OrientedPlane* aPlane = OrientedPlane::SafeDownCast(aFunction)){
480               OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow);
481               SMESH::TVTKPlane aTVTKPlane(anOrientedPlane);
482               anOrientedPlane->Delete();
483               aTVTKPlane->ShallowCopy(aPlane);
484               myPlanes.push_back(aTVTKPlane);
485             }
486           }
487         }
488
489         std::for_each(myPlanes.begin(),myPlanes.end(),
490                       TSetVisiblity(PreviewCheckBox->isChecked()));
491       }
492     }
493     SMESH::RenderViewWindow(aViewWindow);
494   }
495   Sinchronize();
496 }
497
498 //=======================================================================
499 // function : onSelectPlane()
500 // purpose  :
501 //=======================================================================
502 void SMESHGUI_ClippingDlg::onSelectPlane (int theIndex)
503 {
504   if (!myActor || myPlanes.empty())
505     return;
506
507   OrientedPlane* aPlane = myPlanes[theIndex].GetPointer();
508
509   // Orientation
510   SMESH::Orientation anOrientation = aPlane->GetOrientation();
511
512   // Rotations
513   double aRot[2] = {aPlane->myAngle[0], aPlane->myAngle[1]};
514
515   // Set plane parameters in the dialog
516   myIsSelectPlane = true;
517   setDistance(aPlane->GetDistance());
518   setRotation(aRot[0], aRot[1]);
519   switch (anOrientation) {
520   case SMESH::XY:
521     ComboBoxOrientation->setCurrentItem(0);
522     onSelectOrientation(0);
523     break;
524   case SMESH::YZ:
525     ComboBoxOrientation->setCurrentItem(1);
526     onSelectOrientation(1);
527     break;
528   case SMESH::ZX:
529     ComboBoxOrientation->setCurrentItem(2);
530     onSelectOrientation(2);
531     break;
532   }
533   myIsSelectPlane = false;
534 }
535
536 //=======================================================================
537 // function : ClickOnNew()
538 // purpose  :
539 //=======================================================================
540 void SMESHGUI_ClippingDlg::ClickOnNew()
541 {
542   if (!myActor)
543     return;
544
545   if(SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(mySMESHGUI)){
546     OrientedPlane* aPlane = OrientedPlane::New(aViewWindow);
547     SMESH::TVTKPlane aTVTKPlane(aPlane);
548     myPlanes.push_back(aTVTKPlane);
549
550     if (PreviewCheckBox->isChecked())
551       aTVTKPlane->myActor->VisibilityOn();
552     
553     Sinchronize();
554     SetCurrentPlaneParam();
555   }
556 }
557
558 //=======================================================================
559 // function : ClickOnDelete()
560 // purpose  :
561 //=======================================================================
562 void SMESHGUI_ClippingDlg::ClickOnDelete()
563 {
564   if (!myActor || myPlanes.empty())
565     return;
566
567   int aPlaneIndex = ComboBoxPlanes->currentItem();
568
569   SMESH::TPlanes::iterator anIter = myPlanes.begin() + aPlaneIndex;
570   anIter->GetPointer()->myActor->SetVisibility(false);
571   myPlanes.erase(anIter);
572
573   if(AutoApplyCheckBox->isChecked())
574     ClickOnApply();
575
576   Sinchronize();
577   SMESH::RenderViewWindow(SMESH::GetCurrentVtkView());
578 }
579
580 //=======================================================================
581 // function : onSelectOrientation()
582 // purpose  :
583 //=======================================================================
584 void SMESHGUI_ClippingDlg::onSelectOrientation (int theItem)
585 {
586   if (myPlanes.empty())
587     return;
588
589   if      (theItem == 0) {
590     TextLabelRot1->setText(tr("Rotation around X (Y to Z):"));
591     TextLabelRot2->setText(tr("Rotation around Y (X to Z):"));
592   }
593   else if (theItem == 1) {
594     TextLabelRot1->setText(tr("Rotation around Y (Z to X):"));
595     TextLabelRot2->setText(tr("Rotation around Z (Y to X):"));
596   }
597   else if (theItem == 2) {
598     TextLabelRot1->setText(tr("Rotation around Z (X to Y):"));
599     TextLabelRot2->setText(tr("Rotation around X (Z to Y):"));
600   }
601
602   if((QComboBox*)sender() == ComboBoxOrientation)
603     SetCurrentPlaneParam();
604 }
605
606 //=======================================================================
607 // function : Sinchronize()
608 // purpose  :
609 //=======================================================================
610 void SMESHGUI_ClippingDlg::Sinchronize()
611 {
612   int aNbPlanes = myPlanes.size();
613   ComboBoxPlanes->clear();
614
615   QString aName;
616   for(int i = 1; i<=aNbPlanes; i++) {
617     aName = QString(tr("Plane# %1")).arg(i);
618     ComboBoxPlanes->insertItem(aName);
619   }
620
621   int aPos = ComboBoxPlanes->count() - 1;
622   ComboBoxPlanes->setCurrentItem(aPos);
623
624   bool anIsControlsEnable = (aPos >= 0);
625   if (anIsControlsEnable) {
626     onSelectPlane(aPos);
627   } else {
628     ComboBoxPlanes->insertItem(tr("No planes"));
629     SpinBoxRot1->SetValue(0.0);
630     SpinBoxRot2->SetValue(0.0);
631     SpinBoxDistance->SetValue(0.5);
632   }
633
634   buttonDelete->setEnabled(anIsControlsEnable);
635   buttonApply->setEnabled(anIsControlsEnable);
636   PreviewCheckBox->setEnabled(anIsControlsEnable);
637   AutoApplyCheckBox->setEnabled(anIsControlsEnable);
638   ComboBoxOrientation->setEnabled(anIsControlsEnable);
639   SpinBoxDistance->setEnabled(anIsControlsEnable);
640   SpinBoxRot1->setEnabled(anIsControlsEnable);
641   SpinBoxRot2->setEnabled(anIsControlsEnable);
642 }
643
644 //=======================================================================
645 // function : setRotation()
646 // purpose  :
647 //=======================================================================
648 void SMESHGUI_ClippingDlg::setRotation (const double theRot1, const double theRot2)
649 {
650   SpinBoxRot1->SetValue(theRot1);
651   SpinBoxRot2->SetValue(theRot2);
652 }
653
654 //=======================================================================
655 // function : SetCurrentPlaneParam()
656 // purpose  :
657 //=======================================================================
658 void SMESHGUI_ClippingDlg::SetCurrentPlaneParam()
659 {
660   if (myPlanes.empty() || myIsSelectPlane)
661     return;
662
663   int aCurPlaneIndex = ComboBoxPlanes->currentItem();
664
665   OrientedPlane* aPlane = myPlanes[aCurPlaneIndex].GetPointer();
666
667   vtkFloatingPointType aNormal[3];
668   SMESH::Orientation anOrientation;
669   vtkFloatingPointType aDir[3][3] = {{0, 0, 0}, {0, 0, 0}};
670   {
671     static double aCoeff = vtkMath::Pi()/180.0;
672
673     vtkFloatingPointType aRot[2] = {getRotation1(), getRotation2()};
674     aPlane->myAngle[0] = aRot[0];
675     aPlane->myAngle[1] = aRot[1];
676
677     vtkFloatingPointType anU[2] = {cos(aCoeff*aRot[0]), cos(aCoeff*aRot[1])};
678     vtkFloatingPointType aV[2] = {sqrt(1.0-anU[0]*anU[0]), sqrt(1.0-anU[1]*anU[1])};
679     aV[0] = aRot[0] > 0? aV[0]: -aV[0];
680     aV[1] = aRot[1] > 0? aV[1]: -aV[1];
681
682     switch (ComboBoxOrientation->currentItem()) {
683     case 0:
684       anOrientation = SMESH::XY;
685
686       aDir[0][1] = anU[0];
687       aDir[0][2] = aV[0];
688
689       aDir[1][0] = anU[1];
690       aDir[1][2] = aV[1];
691
692       break;
693     case 1:
694       anOrientation = SMESH::YZ;
695
696       aDir[0][2] = anU[0];
697       aDir[0][0] = aV[0];
698
699       aDir[1][1] = anU[1];
700       aDir[1][0] = aV[1];
701
702       break;
703     case 2:
704       anOrientation = SMESH::ZX;
705
706       aDir[0][0] = anU[0];
707       aDir[0][1] = aV[0];
708
709       aDir[1][2] = anU[1];
710       aDir[1][1] = aV[1];
711
712       break;
713     }
714
715     vtkMath::Cross(aDir[1],aDir[0],aNormal);
716     vtkMath::Normalize(aNormal);
717     vtkMath::Cross(aNormal,aDir[1],aDir[0]);
718   }
719
720   aPlane->SetOrientation(anOrientation);
721   aPlane->SetDistance(getDistance());
722
723   myActor->SetPlaneParam(aNormal, getDistance(), aPlane);
724
725   vtkDataSet* aDataSet = myActor->GetInput();
726   vtkFloatingPointType *aPnt = aDataSet->GetCenter();
727
728   vtkFloatingPointType* anOrigin = aPlane->GetOrigin();
729   vtkFloatingPointType aDel = aDataSet->GetLength()/2.0;
730
731   vtkFloatingPointType aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel},
732                                        {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}};
733   vtkFloatingPointType aParam, aPnt0[3], aPnt1[3], aPnt2[3];
734
735   vtkFloatingPointType aPnt01[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 aPnt02[3] = {aPnt01[0] + aNormal[0],
739                                     aPnt01[1] + aNormal[1],
740                                     aPnt01[2] + aNormal[2]};
741   vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0);
742
743   vtkFloatingPointType aPnt11[3] = {aPnt[0] - aDelta[0][0] + aDelta[1][0],
744                                     aPnt[1] - aDelta[0][1] + aDelta[1][1],
745                                     aPnt[2] - aDelta[0][2] + aDelta[1][2]};
746   vtkFloatingPointType aPnt12[3] = {aPnt11[0] + aNormal[0],
747                                     aPnt11[1] + aNormal[1],
748                                     aPnt11[2] + aNormal[2]};
749   vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1);
750
751   vtkFloatingPointType aPnt21[3] = {aPnt[0] + aDelta[0][0] - aDelta[1][0],
752                                     aPnt[1] + aDelta[0][1] - aDelta[1][1],
753                                     aPnt[2] + aDelta[0][2] - aDelta[1][2]};
754   vtkFloatingPointType aPnt22[3] = {aPnt21[0] + aNormal[0],
755                                     aPnt21[1] + aNormal[1],
756                                     aPnt21[2] + aNormal[2]};
757   vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2);
758
759   vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource;
760   aPlaneSource->SetNormal(aNormal[0],aNormal[1],aNormal[2]);
761   aPlaneSource->SetOrigin(aPnt0[0],aPnt0[1],aPnt0[2]);
762   aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]);
763   aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]);
764
765   if(AutoApplyCheckBox->isChecked())
766     ClickOnApply();
767
768   SMESH::RenderViewWindow(SMESH::GetCurrentVtkView());
769 }
770
771 //=======================================================================
772 // function : OnPreviewToggle()
773 // purpose  :
774 //=======================================================================
775 void SMESHGUI_ClippingDlg::OnPreviewToggle (bool theIsToggled)
776 {
777   std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(theIsToggled));
778   SMESH::RenderViewWindow(SMESH::GetCurrentVtkView());
779 }
780
781 //=================================================================================
782 // function : keyPressEvent()
783 // purpose  :
784 //=================================================================================
785 void SMESHGUI_ClippingDlg::keyPressEvent( QKeyEvent* e )
786 {
787   QDialog::keyPressEvent( e );
788   if ( e->isAccepted() )
789     return;
790
791   if ( e->key() == Key_F1 )
792     {
793       e->accept();
794       ClickOnHelp();
795     }
796 }