]> SALOME platform Git repositories - modules/visu.git/blob - src/VISUGUI/VisuGUI_ClippingDlg.cxx
Salome HOME
Copyrights update
[modules/visu.git] / src / VISUGUI / VisuGUI_ClippingDlg.cxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 // 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either 
7 // version 2.1 of the License.
8 // 
9 // This library is distributed in the hope that it will be useful 
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public  
15 // License along with this library; if not, write to the Free Software 
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/
19 //
20
21 #include "VisuGUI_ClippingDlg.h"
22
23 #include "VisuGUI.h"
24 #include "VisuGUI_Tools.h"
25
26 #include "VISU_Prs3d_i.hh"
27 #include "VISU_Result_i.hh"
28
29 #include "VISU_PipeLine.hxx"
30
31 #include "LightApp_SelectionMgr.h"
32
33 #include "SVTK_ViewWindow.h"
34
35 #include "SUIT_Session.h"
36 #include "SUIT_Desktop.h"
37 #include "SUIT_MessageBox.h"
38 #include "SUIT_ResourceMgr.h"
39 #include "SUIT_OverrideCursor.h"
40
41 #include "SALOME_Actor.h"
42
43 // QT Includes
44 #include <qlabel.h>
45 #include <qpushbutton.h>
46 #include <qcombobox.h>
47 #include <qcheckbox.h>
48 #include <qlayout.h>
49 #include <qgroupbox.h>
50 #include <qvalidator.h>
51 #include <qtabwidget.h>
52 #include <qhbuttongroup.h>
53 #include <qradiobutton.h>
54 #include <qspinbox.h>
55
56 // VTK Includes
57 #include <vtkMath.h>
58 #include <vtkCamera.h>
59 #include <vtkRenderer.h>
60 #include <vtkDataSet.h>
61 #include <vtkDataSetMapper.h>
62 #include <vtkImplicitFunction.h>
63 #include <vtkPlaneSource.h>
64 #include <vtkPolyData.h>
65 #include <vtkUnstructuredGrid.h>
66
67 // OCCT Includes
68 #include <gp_Dir.hxx>
69
70 using namespace std;
71
72 namespace VISU {
73   float GetFloat (const QString& theValue, float theDefault)
74   {
75     if (theValue.isEmpty()) return theDefault;
76     SUIT_ResourceMgr* aResourceMgr = VISU::GetResourceMgr();
77     QString aValue = aResourceMgr->stringValue("VISU",theValue);
78     if (aValue.isEmpty()) return theDefault;
79     return aValue.toFloat();
80   }
81
82   void RenderViewWindow (SVTK_ViewWindow* vw)
83   {
84     if (vw) {
85       vw->getRenderer()->ResetCameraClippingRange();
86       vw->Repaint();
87     }
88   }
89
90   void RangeStepAndValidator (QtxDblSpinBox* theSpinBox, double min, double max,
91                               double step, unsigned short decimals)
92   {
93     theSpinBox->setRange(min, max);
94     theSpinBox->setLineStep(step);
95     ((QDoubleValidator*)theSpinBox->validator())->setRange(min, max, decimals);
96   }
97 };
98
99 //=================================================================================
100 //class    : OrientedPlane
101 //purpose  :
102 //=================================================================================
103 class OrientedPlane: public vtkPlane
104 {
105   SVTK_ViewWindow* myViewWindow;
106
107   vtkDataSetMapper* myMapper;
108
109 public:
110   static OrientedPlane * New() {
111     return new OrientedPlane();
112   }
113   static OrientedPlane * New (SVTK_ViewWindow* vw) {
114     return new OrientedPlane(vw);
115   }
116   vtkTypeMacro(OrientedPlane, vtkPlane);
117
118
119   VISU::Orientation myOrientation;
120   float myDistance;
121   double myAngle[2];
122
123   vtkPlaneSource* myPlaneSource;
124   SALOME_Actor *myActor;
125
126   void SetOrientation(VISU::Orientation theOrientation) {myOrientation = theOrientation;}
127   VISU::Orientation GetOrientation() {return myOrientation;}
128
129   void SetDistance(float theDistance) {myDistance = theDistance;}
130   float GetDistance() {return myDistance;}
131
132   void ShallowCopy(OrientedPlane* theOrientedPlane){
133     SetNormal(theOrientedPlane->GetNormal());
134     SetOrigin(theOrientedPlane->GetOrigin());
135
136     myOrientation = theOrientedPlane->GetOrientation();
137     myDistance = theOrientedPlane->GetDistance();
138
139     myAngle[0] = theOrientedPlane->myAngle[0];
140     myAngle[1] = theOrientedPlane->myAngle[1];
141
142     myPlaneSource->SetNormal(theOrientedPlane->myPlaneSource->GetNormal());
143     myPlaneSource->SetOrigin(theOrientedPlane->myPlaneSource->GetOrigin());
144     myPlaneSource->SetPoint1(theOrientedPlane->myPlaneSource->GetPoint1());
145     myPlaneSource->SetPoint2(theOrientedPlane->myPlaneSource->GetPoint2());
146   }
147
148 protected:
149   OrientedPlane(SVTK_ViewWindow* vw):
150     myOrientation(VISU::XY),
151     myDistance(0.5),
152     myViewWindow(vw)
153   {
154     Init();
155     myViewWindow->AddActor(myActor);
156   }
157
158   OrientedPlane():
159     myOrientation(VISU::XY),
160     myDistance(0.5),
161     myViewWindow(NULL)
162   {
163     Init();
164   }
165
166   void Init(){
167     myPlaneSource = vtkPlaneSource::New();
168
169     myAngle[0] = myAngle[1] = 0.0;
170
171     // Create and display actor
172     myMapper = vtkDataSetMapper::New();
173     myMapper->SetInput(myPlaneSource->GetOutput());
174
175     myActor = SALOME_Actor::New();
176     myActor->VisibilityOff();
177     myActor->PickableOff();
178     myActor->SetInfinitive(true);
179     myActor->SetMapper(myMapper);
180
181     vtkProperty* aProp = vtkProperty::New();
182     float anRGB[3];
183
184     SUIT_ResourceMgr* aResourceMgr = VISU::GetResourceMgr();
185
186     QColor aFillColor = aResourceMgr->colorValue("SMESH", "fill_color", QColor(0, 170, 255));
187     anRGB[0] = aFillColor.red()/255.;
188     anRGB[1] = aFillColor.green()/255.;
189     anRGB[2] = aFillColor.blue()/255.;
190     aProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
191     aProp->SetOpacity(0.75);
192     myActor->SetProperty(aProp);
193     aProp->Delete();
194
195     vtkProperty* aBackProp = vtkProperty::New();
196     QColor aBackFaceColor = aResourceMgr->colorValue("SMESH", "backface_color", QColor(0, 0, 255));//@
197     anRGB[0] = aBackFaceColor.red()/255.;
198     anRGB[1] = aBackFaceColor.green()/255.;
199     anRGB[2] = aBackFaceColor.blue()/255.;
200     aBackProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
201     aBackProp->SetOpacity(0.75);
202     myActor->SetBackfaceProperty(aBackProp);
203     aBackProp->Delete();
204   }
205
206   ~OrientedPlane()
207   {
208     if (myViewWindow)
209       myViewWindow->RemoveActor(myActor);
210
211     myActor->Delete();
212
213     myMapper->RemoveAllInputs();
214     myMapper->Delete();
215
216     myPlaneSource->UnRegisterAllOutputs();
217     myPlaneSource->Delete();
218   };
219
220 private:
221   // Not implemented.
222   OrientedPlane(const OrientedPlane&);
223   void operator=(const OrientedPlane&);
224 };
225
226 struct TSetVisiblity {
227   TSetVisiblity(int theIsVisible): myIsVisible(theIsVisible){}
228   void operator()(VISU::TVTKPlane& theOrientedPlane){
229     theOrientedPlane->myActor->SetVisibility(myIsVisible);
230   }
231   int myIsVisible;
232 };
233
234 //=================================================================================
235 // class    : VisuGUI_ClippingDlg()
236 // purpose  :
237 //
238 //=================================================================================
239 VisuGUI_ClippingDlg::VisuGUI_ClippingDlg (VisuGUI* theModule,
240                                           const char* name,
241                                           bool modal,
242                                           WFlags fl)
243   : QDialog(VISU::GetDesktop(theModule), name, modal, WStyle_Customize |
244             WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
245   mySelectionMgr(VISU::GetSelectionMgr(theModule)),
246   myVisuGUI(theModule)
247 {
248   if (!name)
249     setName("VisuGUI_ClippingDlg");
250   setCaption(tr("TITLE"));
251   setSizeGripEnabled(TRUE);
252   QGridLayout* VisuGUI_ClippingDlgLayout = new QGridLayout(this);
253   VisuGUI_ClippingDlgLayout->setSpacing(6);
254   VisuGUI_ClippingDlgLayout->setMargin(11);
255
256   // Controls for selecting, creating, deleting planes
257   QGroupBox* GroupPlanes = new QGroupBox (this, "GroupPlanes");
258   GroupPlanes->setTitle(tr("GRP_PLANES"));
259   GroupPlanes->setColumnLayout(0, Qt::Vertical);
260   GroupPlanes->layout()->setSpacing(0);
261   GroupPlanes->layout()->setMargin(0);
262   QGridLayout* GroupPlanesLayout = new QGridLayout (GroupPlanes->layout());
263   GroupPlanesLayout->setAlignment(Qt::AlignTop);
264   GroupPlanesLayout->setSpacing(6);
265   GroupPlanesLayout->setMargin(11);
266
267   ComboBoxPlanes = new QComboBox (GroupPlanes, "ComboBoxPlanes");
268   GroupPlanesLayout->addWidget(ComboBoxPlanes, 0, 0);
269
270   QSpacerItem* spacerGP = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
271   GroupPlanesLayout->addItem(spacerGP, 0, 1);
272
273   buttonNew = new QPushButton (GroupPlanes, "buttonNew");
274   buttonNew->setText(tr("BUT_NEW"));
275   GroupPlanesLayout->addWidget(buttonNew, 0, 2);
276
277   buttonDelete = new QPushButton(GroupPlanes, "buttonDelete");
278   buttonDelete->setText(tr("BUT_DELETE"));
279   GroupPlanesLayout->addWidget(buttonDelete, 0, 3);
280
281   // Controls for defining plane parameters
282
283   // Tab pane
284   QGroupBox* GroupParameters = new QGroupBox(this, "GroupParameters");
285   GroupParameters->setTitle(tr("GRP_PARAMETERS"));
286   GroupParameters->setColumnLayout(0, Qt::Vertical);
287   GroupParameters->layout()->setSpacing(0);
288   GroupParameters->layout()->setMargin(0);
289   QGridLayout* GroupParametersLayout = new QGridLayout (GroupParameters->layout());
290   GroupParametersLayout->setAlignment(Qt::AlignTop);
291   GroupParametersLayout->setSpacing(6);
292   GroupParametersLayout->setMargin(11);
293
294   TabPane = new QTabWidget (GroupParameters);
295   TabPane->addTab(createParamsTab()   , tr("TAB_NON_STRUCTURED"));
296   TabPane->addTab(createIJKParamsTab(), tr("TAB_IJK_STRUCTURED"));
297   GroupParametersLayout->addWidget(TabPane, 0, 0);
298
299   // "Show preview" and "Auto Apply" check boxes
300
301   PreviewCheckBox = new QCheckBox (tr("SHOW_PREVIEW_CHK"), this);
302   PreviewCheckBox->setChecked(true);
303
304   AutoApplyCheckBox = new QCheckBox (tr("AUTO_APPLY_CHK"), this);
305   AutoApplyCheckBox->setChecked(false);
306
307   // Controls for "Ok", "Apply" and "Close" button
308   QGroupBox* GroupButtons = new QGroupBox (this, "GroupButtons");
309   GroupButtons->setSizePolicy(QSizePolicy((QSizePolicy::SizeType)7,
310                                           (QSizePolicy::SizeType)0, 0, 0,
311                                           GroupButtons->sizePolicy().hasHeightForWidth()));
312   GroupButtons->setGeometry(QRect(10, 10, 281, 48));
313   //GroupButtons->setTitle(tr(""));
314   GroupButtons->setColumnLayout(0, Qt::Vertical);
315   GroupButtons->layout()->setSpacing(0);
316   GroupButtons->layout()->setMargin(0);
317   QGridLayout* GroupButtonsLayout = new QGridLayout (GroupButtons->layout());
318   GroupButtonsLayout->setAlignment(Qt::AlignTop);
319   GroupButtonsLayout->setSpacing(6);
320   GroupButtonsLayout->setMargin(11);
321   buttonCancel = new QPushButton (GroupButtons, "buttonCancel");
322   buttonCancel->setText(tr("BUT_CLOSE"));
323   buttonCancel->setAutoDefault(TRUE);
324   GroupButtonsLayout->addWidget(buttonCancel, 0, 3);
325   buttonApply = new QPushButton (GroupButtons, "buttonApply");
326   buttonApply->setText(tr("BUT_APPLY"));
327   buttonApply->setAutoDefault(TRUE);
328   GroupButtonsLayout->addWidget(buttonApply, 0, 1);
329   QSpacerItem* spacer_9 = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
330   GroupButtonsLayout->addItem(spacer_9, 0, 2);
331   buttonOk = new QPushButton (GroupButtons, "buttonOk");
332   buttonOk->setText(tr("BUT_OK"));
333   buttonOk->setAutoDefault(TRUE);
334   buttonOk->setDefault(TRUE);
335   GroupButtonsLayout->addWidget(buttonOk, 0, 0);
336
337   VisuGUI_ClippingDlgLayout->addMultiCellWidget(GroupPlanes,     0, 0, 0, 1);
338   VisuGUI_ClippingDlgLayout->addMultiCellWidget(GroupParameters, 1, 1, 0, 1);
339   VisuGUI_ClippingDlgLayout->addWidget(PreviewCheckBox,          2,    0);
340   VisuGUI_ClippingDlgLayout->addWidget(AutoApplyCheckBox,        2,    1);
341   VisuGUI_ClippingDlgLayout->addMultiCellWidget(GroupButtons,    3, 3, 0, 1);
342
343   // Initial state
344   VISU::RangeStepAndValidator(SpinBoxDistance, 0.0, 1.0, 0.01, 3);
345   VISU::RangeStepAndValidator(SpinBoxRot1, -180.0, 180.0, 1, 3);
346   VISU::RangeStepAndValidator(SpinBoxRot2, -180.0, 180.0, 1, 3);
347
348   ComboBoxOrientation->insertItem(tr("PARALLEL_XOY_COMBO_ITEM"));
349   ComboBoxOrientation->insertItem(tr("PARALLEL_YOZ_COMBO_ITEM"));
350   ComboBoxOrientation->insertItem(tr("PARALLEL_ZOX_COMBO_ITEM"));
351
352   SpinBoxDistance->setValue(0.5);
353
354   myPrs3d = 0;
355   myIsSelectPlane = false;
356   onSelectionChanged();
357
358   // signals and slots connections :
359   connect(ComboBoxPlanes         , SIGNAL(activated(int))           , this, SLOT(onSelectPlane(int)));
360   connect(buttonNew              , SIGNAL(clicked())                , this, SLOT(ClickOnNew()));
361   connect(buttonDelete           , SIGNAL(clicked())                , this, SLOT(ClickOnDelete()));
362   connect(ComboBoxOrientation    , SIGNAL(activated(int))           , this, SLOT(onSelectOrientation(int)));
363   connect(SpinBoxDistance        , SIGNAL(valueChanged(double))     , this, SLOT(SetCurrentPlaneParam()));
364   connect(SpinBoxRot1            , SIGNAL(valueChanged(double))     , this, SLOT(SetCurrentPlaneParam()));
365   connect(SpinBoxRot2            , SIGNAL(valueChanged(double))     , this, SLOT(SetCurrentPlaneParam()));
366   connect(ButtonGroupIJKAxis     , SIGNAL(clicked(int))             , this, SLOT(onIJKAxisChanged(int)));
367   connect(SpinBoxIJKIndex        , SIGNAL(valueChanged(int))        , this, SLOT(SetCurrentPlaneIJKParam()));
368   connect(CheckBoxIJKPlaneReverse, SIGNAL(toggled(bool))            , this, SLOT(SetCurrentPlaneIJKParam()));
369   connect(TabPane                , SIGNAL(currentChanged (QWidget*)), this, SLOT(onTabChanged(QWidget*)));
370
371   connect(PreviewCheckBox  , SIGNAL(toggled(bool)), this, SLOT(OnPreviewToggle(bool)));
372   connect(AutoApplyCheckBox, SIGNAL(toggled(bool)), this, SLOT(ClickOnApply()));
373
374   connect(buttonOk    , SIGNAL(clicked()), this, SLOT(ClickOnOk()));
375   connect(buttonApply , SIGNAL(clicked()), this, SLOT(ClickOnApply()));
376   connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()));
377
378   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionChanged()));
379
380   this->show();
381 }
382
383 //=================================================================================
384 // function : ~VisuGUI_ClippingDlg()
385 // purpose  :
386 //=================================================================================
387 VisuGUI_ClippingDlg::~VisuGUI_ClippingDlg()
388 {
389   // no need to delete child widgets, Qt does it all for us
390   std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
391   VISU::RenderViewWindow(VISU::GetViewWindow(myVisuGUI));
392 }
393
394 //=================================================================================
395 // function : createParamsTab
396 // purpose  :
397 //=================================================================================
398 QWidget* VisuGUI_ClippingDlg::createParamsTab()
399 {
400   QFrame* GroupParameters = new QFrame(this);
401   QGridLayout* GroupParametersLayout = new QGridLayout(GroupParameters);
402   GroupParametersLayout->setAlignment(Qt::AlignTop);
403   GroupParametersLayout->setSpacing(6);
404   GroupParametersLayout->setMargin(11);
405
406   TextLabelOrientation = new QLabel(GroupParameters, "TextLabelOrientation");
407   TextLabelOrientation->setText(tr("LBL_ORIENTATION"));
408   GroupParametersLayout->addWidget(TextLabelOrientation, 0, 0);
409
410   ComboBoxOrientation = new QComboBox(GroupParameters, "ComboBoxOrientation");
411   GroupParametersLayout->addWidget(ComboBoxOrientation, 0, 1);
412
413   TextLabelDistance = new QLabel(GroupParameters, "TextLabelDistance");
414   TextLabelDistance->setText(tr("LBL_DISTANCE"));
415   GroupParametersLayout->addWidget(TextLabelDistance, 1, 0);
416
417   SpinBoxDistance = new QtxDblSpinBox(GroupParameters, "SpinBoxDistance");
418   GroupParametersLayout->addWidget(SpinBoxDistance, 1, 1);
419
420   TextLabelRot1 = new QLabel(GroupParameters, "TextLabelRot1");
421   TextLabelRot1->setText(tr("LBL_ROTATION_YZ"));
422   GroupParametersLayout->addWidget(TextLabelRot1, 2, 0);
423
424   SpinBoxRot1 = new QtxDblSpinBox(GroupParameters, "SpinBoxRot1");
425   GroupParametersLayout->addWidget(SpinBoxRot1, 2, 1);
426
427   TextLabelRot2 = new QLabel(GroupParameters, "TextLabelRot2");
428   TextLabelRot2->setText(tr("LBL_ROTATION_XZ"));
429   GroupParametersLayout->addWidget(TextLabelRot2, 3, 0);
430
431   SpinBoxRot2 = new QtxDblSpinBox(GroupParameters, "SpinBoxRot2");
432   GroupParametersLayout->addWidget(SpinBoxRot2, 3, 1);
433
434   return GroupParameters;
435 }
436
437 //=================================================================================
438 // function : createIJKParamsTab
439 // purpose  :
440 //=================================================================================
441 QWidget* VisuGUI_ClippingDlg::createIJKParamsTab()
442 {
443   // tab layout
444   WidgetIJKTab = new QFrame(this);
445   QGridLayout* IJKParametersLayout = new QGridLayout(WidgetIJKTab);
446   IJKParametersLayout->setAlignment(Qt::AlignTop);
447   IJKParametersLayout->setSpacing(6);
448   IJKParametersLayout->setMargin(11);
449
450   // Axis group
451   ButtonGroupIJKAxis = new QHButtonGroup (tr("GRP_IJK_AXIS"), WidgetIJKTab);
452   new QRadioButton (tr("I_RADIO_BTN"), ButtonGroupIJKAxis);  // 0
453   new QRadioButton (tr("J_RADIO_BTN"), ButtonGroupIJKAxis);  // 1
454   new QRadioButton (tr("K_RADIO_BTN"), ButtonGroupIJKAxis);  // 2
455   ButtonGroupIJKAxis->setButton(0);
456
457   // Index
458   TextLabelIJKIndex = new QLabel(WidgetIJKTab, "TextLabelIJKIndex");
459   TextLabelIJKIndex->setText(tr("LBL_IJK_INDEX"));
460   SpinBoxIJKIndex = new QSpinBox(WidgetIJKTab, "SpinBoxIJKIndex");
461
462   // Orientation
463   CheckBoxIJKPlaneReverse = new QCheckBox (tr("REVERSE_NORMAL_CHK"), WidgetIJKTab);
464   CheckBoxIJKPlaneReverse->setChecked(false);
465
466   IJKParametersLayout->addMultiCellWidget(ButtonGroupIJKAxis, 0, 0, 0, 1);
467   IJKParametersLayout->addWidget(TextLabelIJKIndex,          1, 0);
468   IJKParametersLayout->addWidget(SpinBoxIJKIndex,            1, 1);
469   IJKParametersLayout->addWidget(CheckBoxIJKPlaneReverse, 2, 0);
470
471   return WidgetIJKTab;
472 }
473
474 //=================================================================================
475 // function : ClickOnApply()
476 // purpose  :
477 //=================================================================================
478 void VisuGUI_ClippingDlg::ClickOnApply()
479 {
480   if (!myPrs3d)
481     return;
482
483   if (SVTK_ViewWindow* aViewWindow = VISU::GetViewWindow(myVisuGUI)) {
484     SUIT_OverrideCursor wc;
485
486     // Save clipping planes, currently applied to the presentation
487     // to enable restoring this state in case of failure.
488     // Refer to bugs IPAL8849, IPAL8850 for more information.
489     typedef vtkSmartPointer<vtkPlane> TPln;
490     typedef std::vector<TPln> TPlns;
491     bool isFailed = false;
492     TPlns anOldPlanes;
493     int iopl = 0, nbOldPlanes = myPrs3d->GetNumberOfClippingPlanes();
494     for (; iopl < nbOldPlanes; iopl++) {
495       anOldPlanes.push_back(myPrs3d->GetClippingPlane(iopl));
496     }
497
498     // Try to apply new clipping
499     myPrs3d->RemoveAllClippingPlanes();
500
501     VISU::TPlanes::iterator anIter = myPlanes.begin();
502     for (; anIter != myPlanes.end(); anIter++) {
503       OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow);
504       anOrientedPlane->ShallowCopy(anIter->GetPointer());
505       if (!myPrs3d->AddClippingPlane(anOrientedPlane)) {
506         isFailed = true;
507       }
508       anOrientedPlane->Delete();
509     }
510
511     // Check contents of the resulting (clipped) presentation data
512     if (!isFailed) {
513       VISU_PipeLine* aPL = myPrs3d->GetPL();
514       VISU_PipeLine::TMapper* aM = aPL->GetMapper();
515       vtkDataSet* aPrsData = aM->GetInput();
516       aPrsData->Update();
517       if (aPrsData->GetNumberOfCells() < 1) {
518         isFailed = true;
519       }
520     }
521
522     if (isFailed) {
523       // Restore previous clipping state because of failure.
524       myPrs3d->RemoveAllClippingPlanes();
525
526       TPlns::iterator anOldIter = anOldPlanes.begin();
527       for (; anOldIter != anOldPlanes.end(); anOldIter++) {
528         myPrs3d->AddClippingPlane(anOldIter->GetPointer());
529       }
530
531       SUIT_MessageBox::warn1(VISU::GetDesktop(myVisuGUI),
532                              tr("WRN_VISU"),
533                              tr("WRN_EMPTY_RESULTING_PRS"),
534                              tr("BUT_OK") );
535     }
536
537     //VISU::RenderViewWindow(aViewWindow);
538     VISU::RepaintViewWindows(myVisuGUI, myIO);
539   }
540 }
541
542 //=================================================================================
543 // function : ClickOnOk()
544 // purpose  :
545 //=================================================================================
546 void VisuGUI_ClippingDlg::ClickOnOk()
547 {
548   ClickOnApply();
549   ClickOnCancel();
550 }
551
552 //=================================================================================
553 // function : ClickOnCancel()
554 // purpose  :
555 //=================================================================================
556 void VisuGUI_ClippingDlg::ClickOnCancel()
557 {
558   close();
559 }
560
561 //=================================================================================
562 // function : onSelectionChanged()
563 // purpose  : Called when selection is changed
564 //=================================================================================
565 void VisuGUI_ClippingDlg::onSelectionChanged()
566 {
567   if (SVTK_ViewWindow* aViewWindow = VISU::GetViewWindow(myVisuGUI)) {
568     Handle(SALOME_InteractiveObject) anIO;
569     CORBA::Object_var anObject = VISU::GetSelectedObj(myVisuGUI, &anIO);
570     myIO = anIO;
571     if (CORBA::is_nil(anObject)) return;
572     PortableServer::ServantBase_var aServant = VISU::GetServant(anObject);
573     if (!aServant.in()) return;
574
575     myPrs3d = dynamic_cast<VISU::Prs3d_i*>(aServant.in());
576     if (myPrs3d) {
577       std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
578       myPlanes.clear();
579
580       float anOffset [3];
581       myPrs3d->GetOffset(anOffset);
582
583       vtkIdType anId = 0, anEnd = myPrs3d->GetNumberOfClippingPlanes();
584       for (; anId < anEnd; anId++) {
585         if (vtkImplicitFunction* aFunction = myPrs3d->GetClippingPlane(anId)) {
586           if (OrientedPlane* aPlane = OrientedPlane::SafeDownCast(aFunction)) {
587             OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow);
588             VISU::TVTKPlane aTVTKPlane(anOrientedPlane);
589             anOrientedPlane->Delete();
590             aTVTKPlane->ShallowCopy(aPlane);
591             aTVTKPlane->myActor->SetPosition(anOffset);
592             myPlanes.push_back(aTVTKPlane);
593           }
594         }
595       }
596
597       std::for_each(myPlanes.begin(),myPlanes.end(),
598                     TSetVisiblity(PreviewCheckBox->isChecked()));
599     }
600
601     // enable/disable IJK tab
602     TabPane->setTabEnabled(WidgetIJKTab, isStructured());
603     Sinchronize();
604     VISU::RenderViewWindow(aViewWindow);
605   }
606 }
607
608 //=================================================================================
609 // function : onSelectPlane()
610 // purpose  :
611 //=================================================================================
612 void VisuGUI_ClippingDlg::onSelectPlane(int theIndex)
613 {
614   if (!myPrs3d || myPlanes.empty())
615     return;
616
617   OrientedPlane* aPlane = myPlanes[theIndex].GetPointer();
618
619   // Orientation
620   VISU::Orientation anOrientation = aPlane->GetOrientation();
621
622   // Rotations
623   double aRot[2] = {aPlane->myAngle[0], aPlane->myAngle[1]};
624
625   // Set plane parameters in the dialog
626   myIsSelectPlane = true;
627   setDistance(aPlane->GetDistance());
628   setRotation(aRot[0], aRot[1]);
629   int item = 0;
630   switch (anOrientation) {
631   case VISU::XY: item = 0; break;
632   case VISU::YZ: item = 1; break;
633   case VISU::ZX: item = 2; break;
634   }
635   ComboBoxOrientation->setCurrentItem(item);
636
637   bool isIJK = (TabPane->currentPage() == WidgetIJKTab);
638   if (isIJK)
639     setIJKByNonStructured();
640   else
641     onSelectOrientation(item);
642
643   myIsSelectPlane = false;
644 }
645
646 //=================================================================================
647 // function : ClickOnNew()
648 // purpose  :
649 //=================================================================================
650 void VisuGUI_ClippingDlg::ClickOnNew()
651 {
652   if (!myPrs3d)
653     return;
654
655   if (SVTK_ViewWindow* aViewWindow = VISU::GetViewWindow(myVisuGUI)) {
656     OrientedPlane* aPlane = OrientedPlane::New(aViewWindow);
657     VISU::TVTKPlane aTVTKPlane(aPlane);
658     myPlanes.push_back(aTVTKPlane);
659
660     float anOffset [3];
661     myPrs3d->GetOffset(anOffset);
662     aTVTKPlane->myActor->SetPosition(anOffset);
663
664     if (PreviewCheckBox->isChecked())
665       aTVTKPlane->myActor->VisibilityOn();
666
667     Sinchronize();
668     SetCurrentPlaneParam();
669   }
670 }
671
672 //=================================================================================
673 // function : ClickOnDelete()
674 // purpose  :
675 //=================================================================================
676 void VisuGUI_ClippingDlg::ClickOnDelete()
677 {
678   if (!myPrs3d || myPlanes.empty())
679     return;
680
681   int aPlaneIndex = ComboBoxPlanes->currentItem();
682
683   VISU::TPlanes::iterator anIter = myPlanes.begin() + aPlaneIndex;
684   anIter->GetPointer()->myActor->SetVisibility(false);
685   myPlanes.erase(anIter);
686
687   if(AutoApplyCheckBox->isChecked())
688     ClickOnApply();
689
690   Sinchronize();
691   if (SVTK_ViewWindow* aViewWindow = VISU::GetViewWindow(myVisuGUI))
692     VISU::RenderViewWindow(aViewWindow);
693 }
694
695 //=================================================================================
696 // function : onSelectOrientation()
697 // purpose  :
698 //=================================================================================
699 void VisuGUI_ClippingDlg::onSelectOrientation(int theItem)
700 {
701   if (myPlanes.empty())
702     return;
703
704   if      (theItem == 0) {
705     TextLabelRot1->setText(tr("LBL_ROTATION_YZ"));
706     TextLabelRot2->setText(tr("LBL_ROTATION_XZ"));
707   }
708   else if (theItem == 1) {
709     TextLabelRot1->setText(tr("LBL_ROTATION_ZX"));
710     TextLabelRot2->setText(tr("LBL_ROTATION_YX"));
711   }
712   else if (theItem == 2) {
713     TextLabelRot1->setText(tr("LBL_ROTATION_XY"));
714     TextLabelRot2->setText(tr("LBL_ROTATION_ZY"));
715   }
716
717   if((QComboBox*)sender() == ComboBoxOrientation)
718     SetCurrentPlaneParam();
719 }
720
721 //=================================================================================
722 // function : Sinchronize()
723 // purpose  : update control values according to plane selection
724 //=================================================================================
725 void VisuGUI_ClippingDlg::Sinchronize()
726 {
727   int aNbPlanes = myPlanes.size();
728   ComboBoxPlanes->clear();
729
730   QString aName;
731   for (int i = 1; i<=aNbPlanes; i++) {
732     aName = QString(tr("PLANES_COMBO_ITEM_i")).arg(i);
733     ComboBoxPlanes->insertItem(aName);
734   }
735
736   int aPos = ComboBoxPlanes->count() - 1;
737   ComboBoxPlanes->setCurrentItem(aPos);
738
739   bool anIsControlsEnable = (aPos >= 0);
740   if (anIsControlsEnable) {
741     onSelectPlane(aPos);
742   } else {
743     ComboBoxPlanes->insertItem(tr("PLANES_COMBO_ITEM_no"));
744     SpinBoxRot1->setValue(0.0);
745     SpinBoxRot2->setValue(0.0);
746     SpinBoxDistance->setValue(0.5);
747   }
748
749   buttonDelete           ->setEnabled(anIsControlsEnable);
750   buttonApply            ->setEnabled(anIsControlsEnable);
751   PreviewCheckBox        ->setEnabled(anIsControlsEnable);
752   AutoApplyCheckBox      ->setEnabled(anIsControlsEnable);
753
754   ComboBoxOrientation    ->setEnabled(anIsControlsEnable);
755   SpinBoxDistance        ->setEnabled(anIsControlsEnable);
756   SpinBoxRot1            ->setEnabled(anIsControlsEnable);
757   SpinBoxRot2            ->setEnabled(anIsControlsEnable);
758
759   ButtonGroupIJKAxis     ->setEnabled(anIsControlsEnable);
760   SpinBoxIJKIndex        ->setEnabled(anIsControlsEnable);
761   CheckBoxIJKPlaneReverse->setEnabled(anIsControlsEnable);
762 }
763
764 //=================================================================================
765 // function : setRotation()
766 // purpose  :
767 //=================================================================================
768 void VisuGUI_ClippingDlg::setRotation(const double theRot1, const double theRot2)
769 {
770   SpinBoxRot1->setValue(theRot1);
771   SpinBoxRot2->setValue(theRot2);
772 }
773
774 //=================================================================================
775 // function : SetCurrentPlaneParam()
776 // purpose  :
777 //=================================================================================
778 void VisuGUI_ClippingDlg::SetCurrentPlaneParam()
779 {
780   if (myPlanes.empty() || myIsSelectPlane)
781     return;
782
783   int aCurPlaneIndex = ComboBoxPlanes->currentItem();
784
785   OrientedPlane* aPlane = myPlanes[aCurPlaneIndex].GetPointer();
786
787   float aNormal[3];
788   VISU::Orientation anOrientation;
789   float aDir[3][3] = {{0, 0, 0}, {0, 0, 0}};
790   {
791     static double aCoeff = vtkMath::Pi()/180.0;
792
793     float aRot[2] = {getRotation1(), getRotation2()};
794     aPlane->myAngle[0] = aRot[0];
795     aPlane->myAngle[1] = aRot[1];
796
797     float anU[2] = {cos(aCoeff*aRot[0]), cos(aCoeff*aRot[1])};
798     float aV[2] = {sqrt(1.0-anU[0]*anU[0]), sqrt(1.0-anU[1]*anU[1])};
799     aV[0] = aRot[0] > 0? aV[0]: -aV[0];
800     aV[1] = aRot[1] > 0? aV[1]: -aV[1];
801
802     switch (ComboBoxOrientation->currentItem()) {
803     case 0:
804       anOrientation = VISU::XY;
805
806       aDir[0][1] = anU[0];
807       aDir[0][2] = aV[0];
808
809       aDir[1][0] = anU[1];
810       aDir[1][2] = aV[1];
811
812       break;
813     case 1:
814       anOrientation = VISU::YZ;
815
816       aDir[0][2] = anU[0];
817       aDir[0][0] = aV[0];
818
819       aDir[1][1] = anU[1];
820       aDir[1][0] = aV[1];
821
822       break;
823     case 2:
824       anOrientation = VISU::ZX;
825
826       aDir[0][0] = anU[0];
827       aDir[0][1] = aV[0];
828
829       aDir[1][2] = anU[1];
830       aDir[1][1] = aV[1];
831
832       break;
833     }
834
835     vtkMath::Cross(aDir[1],aDir[0],aNormal);
836     vtkMath::Normalize(aNormal);
837     vtkMath::Cross(aNormal,aDir[1],aDir[0]);
838   }
839
840   aPlane->SetOrientation(anOrientation);
841   aPlane->SetDistance(getDistance());
842
843   myPrs3d->SetPlaneParam(aNormal, 1. - getDistance(), aPlane);
844
845   vtkDataSet* aDataSet = myPrs3d->GetInput();
846   float *aPnt = aDataSet->GetCenter();
847
848   float* anOrigin = aPlane->GetOrigin();
849   float aDel = aDataSet->GetLength()/2.0;
850
851   float aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel},
852                         {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}};
853   float aParam, aPnt0[3], aPnt1[3], aPnt2[3];
854
855   float aPnt01[3] = {aPnt[0] - aDelta[0][0] - aDelta[1][0],
856                      aPnt[1] - aDelta[0][1] - aDelta[1][1],
857                      aPnt[2] - aDelta[0][2] - aDelta[1][2]};
858   float aPnt02[3] = {aPnt01[0] + aNormal[0],
859                       aPnt01[1] + aNormal[1],
860                       aPnt01[2] + aNormal[2]};
861   vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0);
862
863   float aPnt11[3] = {aPnt[0] - aDelta[0][0] + aDelta[1][0],
864                      aPnt[1] - aDelta[0][1] + aDelta[1][1],
865                      aPnt[2] - aDelta[0][2] + aDelta[1][2]};
866   float aPnt12[3] = {aPnt11[0] + aNormal[0],
867                      aPnt11[1] + aNormal[1],
868                      aPnt11[2] + aNormal[2]};
869   vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1);
870
871   float aPnt21[3] = {aPnt[0] + aDelta[0][0] - aDelta[1][0],
872                      aPnt[1] + aDelta[0][1] - aDelta[1][1],
873                      aPnt[2] + aDelta[0][2] - aDelta[1][2]};
874   float aPnt22[3] = {aPnt21[0] + aNormal[0],
875                      aPnt21[1] + aNormal[1],
876                      aPnt21[2] + aNormal[2]};
877   vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2);
878
879   vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource;
880   aPlaneSource->SetNormal(aNormal[0],aNormal[1],aNormal[2]);
881   aPlaneSource->SetOrigin(aPnt0[0],aPnt0[1],aPnt0[2]);
882   aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]);
883   aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]);
884
885   if (AutoApplyCheckBox->isChecked())
886     ClickOnApply();
887
888   if (SVTK_ViewWindow* vw = VISU::GetViewWindow(myVisuGUI))
889     VISU::RenderViewWindow(vw);
890 }
891
892 //=================================================================================
893 // function : onTabChanged
894 // purpose  :
895 //=================================================================================
896 void VisuGUI_ClippingDlg::onTabChanged(QWidget* newTab)
897 {
898   if (newTab == WidgetIJKTab) // IJK
899     setIJKByNonStructured();
900   else {
901     // set correct labels of rotation spin boxes
902     onSelectOrientation(ComboBoxOrientation->currentItem());
903   }
904 }
905
906 //=================================================================================
907 // function : SetCurrentPlaneIJKParam
908 // purpose  : set non structured parameters by IJK parameters
909 //=================================================================================
910 void VisuGUI_ClippingDlg::SetCurrentPlaneIJKParam()
911 {
912   if (myPlanes.empty() || myIsSelectPlane || !WidgetIJKTab->isEnabled())
913     return;
914
915   VISU::Result_i* result = myPrs3d ? myPrs3d->GetResult() : 0;
916   if (!result)
917     return;
918
919   // get axis data
920   int i, axId = ButtonGroupIJKAxis->id (ButtonGroupIJKAxis->selected());
921   VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) axId;
922   gp_Dir dir;
923   const vector<float> * values =
924     result->GetAxisInfo(myPrs3d->GetMeshName(), axis, dir);
925   if (!values)
926     return;
927
928   // find distance;
929   int index = SpinBoxIJKIndex->value();
930   float distance = 0;
931   if (index < values->size())
932     distance = (*values)[ index ];
933
934   // find id of axis closest to dir
935   // 0  || X-Y - axis Z
936   // 1  || Y-Z - azis X
937   // 2  || Z-X - axiz Y
938   double cos[3] = { gp::DZ() * dir, gp::DX() * dir, gp::DY() * dir };
939   double maxCos = 0;
940   for (i = 0; i < 3; ++i) {
941     if (Abs(cos[ i ]) > Abs (maxCos)) {
942       maxCos = cos[ i ];
943       axId = i;
944     }
945   }
946   // find rotation angles
947   float angle[2];
948   int rotId[2] = {
949     (axId == 0) ? 2 : axId - 1,
950     (axId == 2) ? 0 : axId + 1
951     };
952   static double aCoeff = 180.0/vtkMath::Pi();
953   for (i = 0; i < 2; ++i) {
954     float cosin = cos[ rotId[ i ]];
955     if (maxCos < 0)
956       cosin = -cosin;
957     angle[ i ] = asin(cosin) * aCoeff;
958     if (maxCos < 0)
959       angle[ i ] += 180. * (angle[ i ] < 0 ? 1. : -1.);
960   }
961   if (CheckBoxIJKPlaneReverse->isChecked()) {
962     angle[ 0 ] += 180. * (angle[ 0 ] < 0 ? 1. : -1.);
963     distance = 1. - distance;
964   }
965   if (maxCos < 0)
966     distance = 1. - distance;
967
968   // set paramerets
969   myIsSelectPlane = true;
970   ComboBoxOrientation->setCurrentItem(axId);
971   setRotation(-angle[0], -angle[1]);
972   setDistance(distance);
973   myIsSelectPlane = false;
974
975   SetCurrentPlaneParam();
976 }
977
978 //=================================================================================
979 // function : setIJKByNonStructured
980 // purpose  : convert current non structured parameters to structured ones
981 //=================================================================================
982 void VisuGUI_ClippingDlg::setIJKByNonStructured()
983 {
984   if (!myPrs3d || myPlanes.empty() || !myPrs3d->GetResult())
985     return;
986
987   // get plane normal
988   int planeIndex = ComboBoxPlanes->currentItem();
989   OrientedPlane* plane = myPlanes[ planeIndex ].GetPointer();
990   vtkPlaneSource* planeSource = plane->myPlaneSource;
991   float * planeNormal = planeSource->GetNormal();
992   gp_Dir normal(planeNormal[0], planeNormal[1], planeNormal[2]);
993
994   // find a grid axis most co-directed with plane normal
995   // and cartesian axis most co-directed with plane normal
996   int i, maxAx = 0, gridAxId = 0;
997   gp_Dir dir, gridDir;
998   double maxDot = 0;
999   const vector<float> *curValues, *values = 0;
1000   VISU::Result_i* result = myPrs3d->GetResult();
1001   for (i = 0; i < 3; ++i) {
1002     VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) i;
1003     curValues = result->GetAxisInfo(myPrs3d->GetMeshName(), axis, dir);
1004     if (curValues) {
1005       double dot = normal * dir;
1006       if (Abs(dot) > Abs(maxDot)) {
1007         maxDot = dot;
1008         gridDir = dir;
1009         values = curValues;
1010         gridAxId = i;
1011       }
1012     }
1013     if (Abs (planeNormal[ maxAx ]) < Abs (planeNormal[ i ]))
1014       maxAx = i;
1015   }
1016   gp_XYZ axDir(0,0,0);
1017   axDir.SetCoord(maxAx + 1, 1.);
1018
1019   // find index value
1020   double v = SpinBoxDistance->value();
1021   // reverse value?
1022   bool reverse = (normal * axDir < 0); // normal and axis are opposite
1023   if (gridDir * axDir < 0) // grid dir and axis are opposite
1024     reverse = !reverse;
1025   if (reverse)
1026     v = 1. - v;
1027   for (i = 0; i < values->size(); ++i)
1028     if ((*values)[ i ] > v)
1029       break;
1030   if (i == values->size())
1031     --i;
1032   if (i != 0 && (*values)[ i ] - v > v - (*values)[ i - 1])
1033     --i;
1034
1035   // set control values
1036   myIsSelectPlane = true;
1037   CheckBoxIJKPlaneReverse->setChecked(normal * axDir < 0);
1038   SpinBoxIJKIndex->setValue(i);
1039   ButtonGroupIJKAxis->setButton(gridAxId);
1040   onIJKAxisChanged(gridAxId); // update label and range of index
1041   myIsSelectPlane = false;
1042
1043   SetCurrentPlaneIJKParam();
1044 }
1045
1046 //=================================================================================
1047 // function : isStructured
1048 // purpose  : return true if mesh is structured
1049 //=================================================================================
1050 bool VisuGUI_ClippingDlg::isStructured() const
1051 {
1052   VISU::Result_i* result = myPrs3d ? myPrs3d->GetResult() : 0;
1053   if (result) {
1054     gp_Dir dir;
1055     return result->GetAxisInfo(myPrs3d->GetMeshName(),
1056                                VISU::Result_i::AXIS_X,
1057                                dir);
1058   }
1059   return false;
1060 }
1061
1062 //=================================================================================
1063 // function : onIJKAxisChanged
1064 // purpose  : update Index range and call SetCurrentPlaneParam()
1065 //=================================================================================
1066 void VisuGUI_ClippingDlg::onIJKAxisChanged(int axisId)
1067 {
1068   // set index range
1069   int maxIndex = 0;
1070   VISU::Result_i* result = myPrs3d ? myPrs3d->GetResult() : 0;
1071   if (result) {
1072     VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) axisId;
1073     gp_Dir dir;
1074     const vector<float> * indices = result->GetAxisInfo(myPrs3d->GetMeshName(),
1075                                                         axis, dir);
1076     if (indices)
1077       maxIndex = indices->size() - 1;
1078   }
1079   QString text = tr("LBL_IJK_INDEX_TO_arg").arg(maxIndex);
1080   TextLabelIJKIndex->setText(text);
1081   SpinBoxIJKIndex->setRange(0, maxIndex);
1082
1083   if (SpinBoxIJKIndex->value() > maxIndex)
1084     SpinBoxIJKIndex->setValue(0);
1085
1086   SetCurrentPlaneIJKParam();
1087 }
1088
1089 //=================================================================================
1090 // function : OnPreviewToggle()
1091 // purpose  :
1092 //=================================================================================
1093 void VisuGUI_ClippingDlg::OnPreviewToggle (bool theIsToggled)
1094 {
1095   std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(theIsToggled));
1096   if (SVTK_ViewWindow* vw = VISU::GetViewWindow(myVisuGUI))
1097     VISU::RenderViewWindow(vw);
1098 }