Salome HOME
0021105: EDF 1179 SMESH: Efficiency of clipping plane in VTK viewer
[modules/visu.git] / src / VISUGUI / VisuGUI_ClippingDlg.cxx
1 //  Copyright (C) 2007-2010  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
23 #include "VisuGUI_ClippingDlg.h"
24
25 #include "VisuGUI.h"
26 #include "VisuGUI_Tools.h"
27 #include "VisuGUI_ViewTools.h"
28
29 #include "VISU_Prs3d_i.hh"
30 #include "VISU_Result_i.hh"
31 #include "VISU_ColoredPrs3dHolder_i.hh"
32
33 #include "VISU_PipeLine.hxx"
34 #include "VISU_DataSetActor.h"
35
36 #include <SalomeApp_IntSpinBox.h>
37 #include <SalomeApp_DoubleSpinBox.h>
38
39 #include "LightApp_SelectionMgr.h"
40 #include "LightApp_Application.h"
41
42 #include "SVTK_ViewWindow.h"
43 #include <VTKViewer_Utilities.h>
44
45 #include "SUIT_Session.h"
46 #include "SUIT_Desktop.h"
47 #include "SUIT_MessageBox.h"
48 #include "SUIT_ResourceMgr.h"
49 #include "SUIT_OverrideCursor.h"
50
51 #include "SALOME_Actor.h"
52 #include "VISU_ViewManager_i.hh"
53
54 // QT Includes
55 #include <QLabel>
56 #include <QComboBox>
57 #include <QCheckBox>
58 #include <QLayout>
59 #include <QGroupBox>
60 #include <QButtonGroup>
61 #include <QValidator>
62 #include <QTabWidget>
63 #include <QRadioButton>
64 #include <QKeyEvent>
65 #include <QPushButton>
66 #include <QListWidget>
67 #include <QVBoxLayout>
68 #include <QHBoxLayout>
69 #include <QStackedWidget>
70
71 // VTK Includes
72 #include <vtkMath.h>
73 #include <vtkCamera.h>
74 #include <vtkRenderer.h>
75 #include <vtkDataSet.h>
76 #include <vtkDataSetMapper.h>
77 #include <vtkImplicitFunction.h>
78 #include <vtkPlaneSource.h>
79 #include <vtkPolyData.h>
80 #include <vtkUnstructuredGrid.h>
81 #include <vtkProperty.h>
82 #include <vtkImplicitFunctionCollection.h>
83
84 // OCCT Includes
85 #include <gp_Dir.hxx>
86
87 using namespace std;
88
89 namespace VISU {
90   float GetFloat (const QString& theValue, float theDefault)
91   {
92     if (theValue.isEmpty()) return theDefault;
93     SUIT_ResourceMgr* aResourceMgr = VISU::GetResourceMgr();
94     QString aValue = aResourceMgr->stringValue("VISU",theValue);
95     if (aValue.isEmpty()) return theDefault;
96     return aValue.toFloat();
97   }
98
99   void RenderViewWindow (SVTK_ViewWindow* vw)
100   {
101     if (vw) {
102       vw->getRenderer()->ResetCameraClippingRange();
103       vw->Repaint();
104     }
105   }
106 };
107
108 //=================================================================================
109 //class    : OrientedPlane
110 //purpose  :
111 //=================================================================================
112 OrientedPlane* OrientedPlane::New() 
113 {
114   return new OrientedPlane();
115 }
116
117 OrientedPlane* OrientedPlane::New (SVTK_ViewWindow* vw) 
118 {
119   return new OrientedPlane(vw);
120 }
121
122 void OrientedPlane::SetOrientation(VISU::Orientation theOrientation) 
123 {
124   myOrientation = theOrientation;
125 }
126
127 VISU::Orientation OrientedPlane::GetOrientation() 
128 {
129   return myOrientation;
130 }
131
132 void OrientedPlane::SetDistance(float theDistance) 
133 {
134   myDistance = theDistance;
135 }
136
137 float OrientedPlane::GetDistance() 
138 {
139   return myDistance;
140 }
141
142 void OrientedPlane::ShallowCopy(OrientedPlane* theOrientedPlane)
143 {
144   SetNormal(theOrientedPlane->GetNormal());
145   SetOrigin(theOrientedPlane->GetOrigin());
146   
147   myOrientation = theOrientedPlane->GetOrientation();
148   myDistance = theOrientedPlane->GetDistance();
149   
150   myAngle[0] = theOrientedPlane->myAngle[0];
151   myAngle[1] = theOrientedPlane->myAngle[1];
152   
153   myPlaneSource->SetNormal(theOrientedPlane->myPlaneSource->GetNormal());
154   myPlaneSource->SetOrigin(theOrientedPlane->myPlaneSource->GetOrigin());
155   myPlaneSource->SetPoint1(theOrientedPlane->myPlaneSource->GetPoint1());
156   myPlaneSource->SetPoint2(theOrientedPlane->myPlaneSource->GetPoint2());
157 }
158
159 OrientedPlane::OrientedPlane(SVTK_ViewWindow* vw):
160   myOrientation(VISU::XY),
161   myDistance(0.5),
162   myViewWindow(vw)
163 {
164   Init();
165   myViewWindow->AddActor(myActor, false, false); // don't adjust actors
166 }
167
168 OrientedPlane::OrientedPlane():
169   myOrientation(VISU::XY),
170   myDistance(0.5),
171   myViewWindow(NULL)
172 {
173   Init();
174 }
175
176 void OrientedPlane::Init()
177 {
178   myPlaneSource = vtkPlaneSource::New();
179   
180   myAngle[0] = myAngle[1] = 0.0;
181
182   // Create and display actor
183   myMapper = vtkDataSetMapper::New();
184   myMapper->SetInput(myPlaneSource->GetOutput());
185
186   myActor = SALOME_Actor::New();
187   myActor->VisibilityOff();
188   myActor->PickableOff();
189   myActor->SetInfinitive(true);
190   myActor->SetMapper(myMapper);
191   
192   vtkProperty* aProp = vtkProperty::New();
193   float anRGB[3];
194   
195   SUIT_ResourceMgr* aResourceMgr = VISU::GetResourceMgr();
196   
197   QColor aFillColor = aResourceMgr->colorValue("SMESH", "fill_color", QColor(0, 170, 255));
198   anRGB[0] = aFillColor.red()/255.;
199   anRGB[1] = aFillColor.green()/255.;
200   anRGB[2] = aFillColor.blue()/255.;
201   aProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
202   aProp->SetOpacity(0.75);
203   myActor->SetProperty(aProp);
204   aProp->Delete();
205   
206   vtkProperty* aBackProp = vtkProperty::New();
207   QColor aBackFaceColor = aResourceMgr->colorValue("SMESH", "backface_color", QColor(0, 0, 255));//@
208   anRGB[0] = aBackFaceColor.red()/255.;
209   anRGB[1] = aBackFaceColor.green()/255.;
210   anRGB[2] = aBackFaceColor.blue()/255.;
211   aBackProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
212   aBackProp->SetOpacity(0.75);
213   myActor->SetBackfaceProperty(aBackProp);
214   aBackProp->Delete();
215 }
216
217 OrientedPlane::~OrientedPlane()
218 {
219   if ( !myViewWindow.isNull() )
220     myViewWindow->RemoveActor(myActor);
221
222   myActor->Delete();
223
224   myMapper->RemoveAllInputs();
225   myMapper->Delete();
226   
227   // commented: porting to vtk 5.0
228   //myPlaneSource->UnRegisterAllOutputs();
229   myPlaneSource->Delete();
230 }
231
232 struct TSetVisiblity {
233   TSetVisiblity(int theIsVisible): myIsVisible(theIsVisible){}
234   void operator()(VISU::TVTKPlane& theOrientedPlane){
235     theOrientedPlane->myActor->SetVisibility(myIsVisible);
236   }
237   int myIsVisible;
238 };
239
240 //=================================================================================
241 // class    : VisuGUI_ClippingDlg()
242 // purpose  :
243 //
244 //=================================================================================
245 VisuGUI_ClippingDlg::VisuGUI_ClippingDlg (VisuGUI* theModule,
246                                           bool modal )
247   : QDialog(VISU::GetDesktop(theModule), Qt::WindowTitleHint | Qt::WindowSystemMenuHint ),
248     mySelectionMgr(VISU::GetSelectionMgr(theModule)),
249     myVisuGUI(theModule),
250     myPrs3d(0),
251     myIsSelectPlane(false),
252     myDSActor(0)
253 {
254   setWindowTitle(tr("TITLE"));
255   setSizeGripEnabled(TRUE);
256   setAttribute( Qt::WA_DeleteOnClose, true );
257
258   QVBoxLayout* VisuGUI_ClippingDlgLayout = new QVBoxLayout(this);
259   VisuGUI_ClippingDlgLayout->setSpacing(6);
260   VisuGUI_ClippingDlgLayout->setMargin(11);
261   
262   QStackedWidget* aStackWidget = new QStackedWidget(this);
263   VisuGUI_ClippingDlgLayout->addWidget(aStackWidget);
264   // Local planes
265   QWidget* aLocalPlanes = new QWidget(aStackWidget);
266   QVBoxLayout* aLocalLayout = new QVBoxLayout(aLocalPlanes);
267   aStackWidget->addWidget(aLocalPlanes);
268
269   // Controls for selecting, creating, deleting planes
270   QGroupBox* GroupPlanes = new QGroupBox (tr("GRP_PLANES"),  aLocalPlanes);
271   QGridLayout* GroupPlanesLayout = new QGridLayout (GroupPlanes);
272   GroupPlanesLayout->setAlignment(Qt::AlignTop);
273   GroupPlanesLayout->setSpacing(6);
274   GroupPlanesLayout->setMargin(11);
275   aLocalLayout->addWidget(GroupPlanes);
276
277   ComboBoxPlanes = new QComboBox (GroupPlanes);
278   GroupPlanesLayout->addWidget(ComboBoxPlanes, 0, 0);
279
280   QSpacerItem* spacerGP = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
281   GroupPlanesLayout->addItem(spacerGP, 0, 1);
282
283   buttonNew = new QPushButton (GroupPlanes );
284   buttonNew->setText(tr("BUT_NEW"));
285   GroupPlanesLayout->addWidget(buttonNew, 0, 2);
286
287   buttonDelete = new QPushButton(GroupPlanes);
288   buttonDelete->setText(tr("BUT_DELETE"));
289   GroupPlanesLayout->addWidget(buttonDelete, 0, 3);
290
291   // Controls for defining plane parameters
292
293   // Tab pane
294   QGroupBox* GroupParameters = new QGroupBox(tr("GRP_PARAMETERS"), aLocalPlanes);
295   QGridLayout* GroupParametersLayout = new QGridLayout (GroupParameters);
296   GroupParametersLayout->setAlignment(Qt::AlignTop);
297   GroupParametersLayout->setSpacing(6);
298   GroupParametersLayout->setMargin(11);
299   aLocalLayout->addWidget(GroupParameters);
300
301   TabPane = new QTabWidget (GroupParameters);
302   TabPane->addTab(createParamsTab()   , tr("TAB_NON_STRUCTURED"));
303   TabPane->addTab(createIJKParamsTab(), tr("TAB_IJK_STRUCTURED"));
304   GroupParametersLayout->addWidget(TabPane, 0, 0);
305
306
307
308
309
310   // "Show preview" and "Auto Apply" check boxes
311   QHBoxLayout* aCheckBoxLayout = new QHBoxLayout(this);
312   VisuGUI_ClippingDlgLayout->addLayout(aCheckBoxLayout);
313
314   PreviewCheckBox = new QCheckBox (tr("SHOW_PREVIEW_CHK"), this);
315   PreviewCheckBox->setChecked(true);
316   aCheckBoxLayout->addWidget(PreviewCheckBox);
317   aCheckBoxLayout->addStretch();
318
319   AutoApplyCheckBox = new QCheckBox (tr("AUTO_APPLY_CHK"), this);
320   AutoApplyCheckBox->setChecked(false);
321   aCheckBoxLayout->addWidget(AutoApplyCheckBox);
322
323   // Controls for "Ok", "Apply" and "Close" button
324   QGroupBox* GroupButtons = new QGroupBox (this);
325   VisuGUI_ClippingDlgLayout->addWidget(GroupButtons);
326   QSizePolicy aSizePolicy(QSizePolicy::Expanding,
327                           QSizePolicy::Fixed );
328   aSizePolicy.setHeightForWidth( GroupButtons->sizePolicy().hasHeightForWidth() );
329   aSizePolicy.setHorizontalStretch( 0 );
330   aSizePolicy.setVerticalStretch( 0 );
331   GroupButtons->setSizePolicy( aSizePolicy );
332   GroupButtons->setGeometry(QRect(10, 10, 281, 48));
333   QGridLayout* GroupButtonsLayout = new QGridLayout (GroupButtons);
334   GroupButtons->setLayout(GroupButtonsLayout);
335   GroupButtonsLayout->setAlignment(Qt::AlignTop);
336   GroupButtonsLayout->setSpacing(6);
337   GroupButtonsLayout->setMargin(11);
338   buttonHelp = new QPushButton (GroupButtons);
339   buttonHelp->setText(tr("BUT_HELP"));
340   buttonHelp->setAutoDefault(TRUE);
341   GroupButtonsLayout->addWidget(buttonHelp, 0, 4);
342   buttonCancel = new QPushButton (GroupButtons);
343   buttonCancel->setText(tr("BUT_CLOSE"));
344   buttonCancel->setAutoDefault(TRUE);
345   GroupButtonsLayout->addWidget(buttonCancel, 0, 3);
346   buttonApply = new QPushButton (GroupButtons);
347   buttonApply->setText(tr("BUT_APPLY"));
348   buttonApply->setAutoDefault(TRUE);
349   GroupButtonsLayout->addWidget(buttonApply, 0, 1);
350   QSpacerItem* spacer_9 = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
351   GroupButtonsLayout->addItem(spacer_9, 0, 2);
352   buttonOk = new QPushButton (GroupButtons);
353   buttonOk->setText(tr("BUT_OK"));
354   buttonOk->setAutoDefault(TRUE);
355   buttonOk->setDefault(TRUE);
356   GroupButtonsLayout->addWidget(buttonOk, 0, 0);
357
358   // Initial state
359   VISU::initSpinBox( SpinBoxDistance, 0., 1., .01, "length_precision" );
360   VISU::initSpinBox( SpinBoxRot1, -180., 180., 1., "angle_precision" );
361   VISU::initSpinBox( SpinBoxRot2, -180., 180., 1., "angle_precision" );  
362
363   ComboBoxOrientation->addItem(tr("PARALLEL_XOY_COMBO_ITEM"));
364   ComboBoxOrientation->addItem(tr("PARALLEL_YOZ_COMBO_ITEM"));
365   ComboBoxOrientation->addItem(tr("PARALLEL_ZOX_COMBO_ITEM"));
366
367   SpinBoxDistance->setValue(0.5);
368
369   onSelectionChanged();
370
371   // signals and slots connections :
372   connect(ComboBoxPlanes         , SIGNAL(activated(int))           , this, SLOT(onSelectPlane(int)));
373   connect(buttonNew              , SIGNAL(clicked())                , this, SLOT(ClickOnNew()));
374   connect(buttonDelete           , SIGNAL(clicked())                , this, SLOT(ClickOnDelete()));
375   connect(ComboBoxOrientation    , SIGNAL(activated(int))           , this, SLOT(onSelectOrientation(int)));
376   connect(SpinBoxDistance        , SIGNAL(valueChanged(double))     , this, SLOT(SetCurrentPlaneParam()));
377   connect(SpinBoxRot1            , SIGNAL(valueChanged(double))     , this, SLOT(SetCurrentPlaneParam()));
378   connect(SpinBoxRot2            , SIGNAL(valueChanged(double))     , this, SLOT(SetCurrentPlaneParam()));
379   connect(ButtonGroupIJKAxis     , SIGNAL(buttonClicked(int))             , this, SLOT(onIJKAxisChanged(int)));
380   connect(SpinBoxIJKIndex        , SIGNAL(valueChanged(int))        , this, SLOT(SetCurrentPlaneIJKParam()));
381   connect(CheckBoxIJKPlaneReverse, SIGNAL(toggled(bool))            , this, SLOT(SetCurrentPlaneIJKParam()));
382   connect(TabPane                , SIGNAL(currentChanged (QWidget*)), this, SLOT(onTabChanged(QWidget*)));
383
384   connect(PreviewCheckBox  , SIGNAL(toggled(bool)), this, SLOT(OnPreviewToggle(bool)));
385   connect(AutoApplyCheckBox, SIGNAL(toggled(bool)), this, SLOT(ClickOnApply()));
386
387   connect(buttonOk    , SIGNAL(clicked()), this, SLOT(ClickOnOk()));
388   connect(buttonApply , SIGNAL(clicked()), this, SLOT(ClickOnApply()));
389   connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()));
390   connect(buttonHelp  , SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
391
392   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionChanged()));
393
394   this->show();
395 }
396
397 //=================================================================================
398 // function : ~VisuGUI_ClippingDlg()
399 // purpose  :
400 //=================================================================================
401 VisuGUI_ClippingDlg::~VisuGUI_ClippingDlg()
402 {
403   // no need to delete child widgets, Qt does it all for us
404   SetPrs3d(NULL);
405   std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
406   VISU::RenderViewWindow(VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI));
407 }
408
409 //=================================================================================
410 // function : createParamsTab
411 // purpose  :
412 //=================================================================================
413 QWidget* VisuGUI_ClippingDlg::createParamsTab()
414 {
415   QFrame* GroupParameters = new QFrame(this);
416   QGridLayout* GroupParametersLayout = new QGridLayout(GroupParameters);
417   GroupParametersLayout->setAlignment(Qt::AlignTop);
418   GroupParametersLayout->setSpacing(6);
419   GroupParametersLayout->setMargin(11);
420
421   TextLabelOrientation = new QLabel(GroupParameters);
422   TextLabelOrientation->setText(tr("LBL_ORIENTATION"));
423   GroupParametersLayout->addWidget(TextLabelOrientation, 0, 0);
424
425   ComboBoxOrientation = new QComboBox(GroupParameters);
426   GroupParametersLayout->addWidget(ComboBoxOrientation, 0, 1);
427
428   TextLabelDistance = new QLabel(GroupParameters);
429   TextLabelDistance->setText(tr("LBL_DISTANCE"));
430   GroupParametersLayout->addWidget(TextLabelDistance, 1, 0);
431
432   SpinBoxDistance = new SalomeApp_DoubleSpinBox(GroupParameters);
433   GroupParametersLayout->addWidget(SpinBoxDistance, 1, 1);
434
435   TextLabelRot1 = new QLabel(GroupParameters);
436   TextLabelRot1->setText(tr("LBL_ROTATION_YZ"));
437   GroupParametersLayout->addWidget(TextLabelRot1, 2, 0);
438
439   SpinBoxRot1 = new SalomeApp_DoubleSpinBox(GroupParameters);
440   GroupParametersLayout->addWidget(SpinBoxRot1, 2, 1);
441
442   TextLabelRot2 = new QLabel(GroupParameters);
443   TextLabelRot2->setText(tr("LBL_ROTATION_XZ"));
444   GroupParametersLayout->addWidget(TextLabelRot2, 3, 0);
445
446   SpinBoxRot2 = new SalomeApp_DoubleSpinBox(GroupParameters);
447   GroupParametersLayout->addWidget(SpinBoxRot2, 3, 1);
448
449   return GroupParameters;
450 }
451
452 //=================================================================================
453 // function : createIJKParamsTab
454 // purpose  :
455 //=================================================================================
456 QWidget* VisuGUI_ClippingDlg::createIJKParamsTab()
457 {
458   // tab layout
459   WidgetIJKTab = new QFrame(this);
460   QGridLayout* IJKParametersLayout = new QGridLayout(WidgetIJKTab);
461   IJKParametersLayout->setAlignment(Qt::AlignTop);
462   IJKParametersLayout->setSpacing(6);
463   IJKParametersLayout->setMargin(11);
464
465   // Axis group
466   ButtonGroupIJKAxis = new QButtonGroup ( WidgetIJKTab);
467   //QGroupBox* aGBGroupBoxIJKAxis= new QGroupBox(tr("GRP_IJK_AXIS"), WidgetIJKTab );
468   GroupBoxIJKAxis= new QGroupBox(tr("GRP_IJK_AXIS"), WidgetIJKTab );
469   QHBoxLayout* aHBLay = new QHBoxLayout( GroupBoxIJKAxis  );
470   ButtonGroupIJKAxis->addButton( new QRadioButton (tr("I_RADIO_BTN"), GroupBoxIJKAxis), 0 );  // 0
471   ButtonGroupIJKAxis->addButton( new QRadioButton (tr("J_RADIO_BTN"), GroupBoxIJKAxis), 1 );  // 1
472   ButtonGroupIJKAxis->addButton( new QRadioButton (tr("K_RADIO_BTN"), GroupBoxIJKAxis), 2 );  // 2
473   ButtonGroupIJKAxis->button(0)->setChecked(true);
474   aHBLay->addWidget( ButtonGroupIJKAxis->button(0) );
475   aHBLay->addWidget( ButtonGroupIJKAxis->button(1) );
476   aHBLay->addWidget( ButtonGroupIJKAxis->button(2) );  
477
478   // Index
479   TextLabelIJKIndex = new QLabel(WidgetIJKTab);
480   TextLabelIJKIndex->setText(tr("LBL_IJK_INDEX"));
481   SpinBoxIJKIndex = new SalomeApp_IntSpinBox(WidgetIJKTab);
482   SpinBoxIJKIndex->setAcceptNames( false );
483
484   // Orientation
485   CheckBoxIJKPlaneReverse = new QCheckBox (tr("REVERSE_NORMAL_CHK"), WidgetIJKTab);
486   CheckBoxIJKPlaneReverse->setChecked(false);
487
488   IJKParametersLayout->addWidget(GroupBoxIJKAxis, 0, 0, 1, 2);
489   IJKParametersLayout->addWidget(TextLabelIJKIndex,          1, 0);
490   IJKParametersLayout->addWidget(SpinBoxIJKIndex,            1, 1);
491   IJKParametersLayout->addWidget(CheckBoxIJKPlaneReverse, 2, 0);
492
493   return WidgetIJKTab;
494 }
495
496 //=================================================================================
497 // function : ClickOnApply()
498 // purpose  :
499 //=================================================================================
500 void VisuGUI_ClippingDlg::ClickOnApply()
501 {
502   applyLocalPlanes();
503 }
504
505
506 //=================================================================================
507 // function : applyLocalPlanes()
508 // purpose  :
509 //=================================================================================
510 void VisuGUI_ClippingDlg::applyLocalPlanes()
511 {
512   if (!myPrs3d)
513     return;
514
515   if (SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI)) {
516     SUIT_OverrideCursor wc;
517
518     QWidget *aCurrWid = this->focusWidget();
519     aCurrWid->clearFocus();
520     aCurrWid->setFocus();
521
522     // Save clipping planes, currently applied to the presentation
523     // to enable restoring this state in case of failure.
524     // Refer to bugs IPAL8849, IPAL8850 for more information.
525     typedef vtkSmartPointer<vtkPlane> TPln;
526     typedef std::vector<TPln> TPlns;
527     bool isFailed = false;
528     TPlns anOldPlanes;
529     int iopl = 0, nbOldPlanes = myPrs3d->GetNumberOfClippingPlanes();
530     for (; iopl < nbOldPlanes; iopl++) {
531       anOldPlanes.push_back(myPrs3d->GetClippingPlane(iopl));
532     }
533
534     // Try to apply new clipping
535     //myPrs3d->RemoveAllClippingPlanes();
536     removeAllClippingPlanes(myPrs3d);
537
538     VISU::TPlanes::iterator anIter = myPlanes.begin();
539     for (; anIter != myPlanes.end(); anIter++) {
540       OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow);
541       anOrientedPlane->ShallowCopy(anIter->GetPointer());
542       if (!myPrs3d->AddClippingPlane(anOrientedPlane)) {
543         isFailed = true;
544       }
545       anOrientedPlane->Delete();
546     }
547
548     // Check contents of the resulting (clipped) presentation data
549     if (!isFailed) {
550       VISU_PipeLine* aPL = myPrs3d->GetPipeLine();
551       vtkMapper* aMapper = aPL->GetMapper();
552       vtkDataSet* aPrsData = aMapper->GetInput();
553       aPrsData->Update();
554       if (aPrsData->GetNumberOfCells() < 1) {
555         isFailed = true;
556       }
557     }
558
559     if (isFailed) {
560       // Restore previous clipping state because of failure.
561       //myPrs3d->RemoveAllClippingPlanes();
562       removeAllClippingPlanes(myPrs3d);
563
564       TPlns::iterator anOldIter = anOldPlanes.begin();
565       for (; anOldIter != anOldPlanes.end(); anOldIter++) {
566         myPrs3d->AddClippingPlane(anOldIter->GetPointer());
567       }
568
569       SUIT_MessageBox::warning(VISU::GetDesktop(myVisuGUI),
570                                tr("WRN_VISU"),
571                                tr("WRN_EMPTY_RESULTING_PRS"),
572                                tr("BUT_OK") );
573     }
574
575     //VISU::RenderViewWindow(aViewWindow);
576     VISU::RepaintViewWindows(myVisuGUI, myIO);
577   }
578 }
579
580
581
582
583 //=================================================================================
584 // function : ClickOnOk()
585 // purpose  :
586 //=================================================================================
587 void VisuGUI_ClippingDlg::ClickOnOk()
588 {
589   ClickOnApply();
590   ClickOnCancel();
591 }
592
593 //=================================================================================
594 // function : ClickOnCancel()
595 // purpose  :
596 //=================================================================================
597 void VisuGUI_ClippingDlg::ClickOnCancel()
598 {
599   close();
600 }
601
602 //=================================================================================
603 // function : ClickOnHelp()
604 // purpose  :
605 //=================================================================================
606 void VisuGUI_ClippingDlg::ClickOnHelp()
607 {
608   QString aHelpFileName = "clipping_page.html";
609   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
610   if (app)
611     app->onHelpContextModule(myVisuGUI ? app->moduleName(myVisuGUI->moduleName()) : QString(""), aHelpFileName);
612   else {
613     QString platform;
614 #ifdef WIN32
615     platform = "winapplication";
616 #else
617     platform = "application";
618 #endif
619     SUIT_MessageBox::warning(0, QObject::tr("WRN_WARNING"),
620                              QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
621                              arg(app->resourceMgr()->stringValue("ExternalBrowser", platform)).arg(aHelpFileName),
622                              QObject::tr("BUT_OK"));
623   }
624 }
625
626 //=================================================================================
627 // function : onSelectionChanged()
628 // purpose  : Called when selection is changed
629 //=================================================================================
630 void VisuGUI_ClippingDlg::onSelectionChanged()
631 {
632   if(SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI)){
633
634     VISU::TSelectionInfo aSelectionInfo = VISU::GetSelectedObjects(myVisuGUI);
635     if(aSelectionInfo.empty())
636       return;
637
638     VISU::TSelectionItem aSelectionItem = aSelectionInfo.front();
639     VISU::Base_i* aBase = aSelectionItem.myObjectInfo.myBase;
640     if(!aBase) 
641       return;
642   
643     Handle(SALOME_InteractiveObject) anIO = aSelectionItem.myIO;
644     if (!anIO.IsNull()) 
645       myIO = anIO;
646
647     //----
648     // rnv: fix for issue 0020114 (EDF VISU 918 : Impossible to 
649     // create a new clipping plane on field presentation)
650     // set last visited presentation from holder as myPrs3d
651     VISU::ColoredPrs3dHolder_i* aHolder = dynamic_cast<VISU::ColoredPrs3dHolder_i*>(aBase);
652     VISU::Prs3d_i* aPrs3d = NULL;
653     if(aHolder) 
654       aPrs3d = aHolder->GetPrs3dDevice();
655     else
656       aPrs3d = dynamic_cast<VISU::Prs3d_i*>(aBase);
657     //----
658     
659     SetPrs3d(aPrs3d);
660     if (myPrs3d) {
661       std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
662       myPlanes.clear();
663
664       CORBA::Float anOffset[3];
665       myPrs3d->GetOffset(anOffset[0],anOffset[1],anOffset[2]);
666
667       vtkIdType anId = 0, anEnd = myPrs3d->GetNumberOfClippingPlanes();
668       for (; anId < anEnd; anId++) {
669         if (vtkImplicitFunction* aFunction = myPrs3d->GetClippingPlane(anId)) {
670           if (OrientedPlane* aPlane = OrientedPlane::SafeDownCast(aFunction)) {
671             OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow);
672             VISU::TVTKPlane aTVTKPlane(anOrientedPlane);
673             anOrientedPlane->Delete();
674             aTVTKPlane->ShallowCopy(aPlane);
675             aTVTKPlane->myActor->SetPosition(anOffset[0],anOffset[1],anOffset[2]);
676             myPlanes.push_back(aTVTKPlane);
677           }
678         }
679       }
680
681       std::for_each(myPlanes.begin(),myPlanes.end(),
682                     TSetVisiblity(PreviewCheckBox->isChecked()));
683     }
684
685     // enable/disable IJK tab
686     TabPane->setTabEnabled(TabPane->indexOf(WidgetIJKTab), isStructured());
687     Sinchronize();
688     VISU::RenderViewWindow(aViewWindow);
689   }
690 }
691
692 //=================================================================================
693 // function : onSelectPlane()
694 // purpose  :
695 //=================================================================================
696 void VisuGUI_ClippingDlg::onSelectPlane(int theIndex)
697 {
698   if (!myPrs3d || myPlanes.empty())
699     return;
700
701   OrientedPlane* aPlane = myPlanes[theIndex].GetPointer();
702
703   // Orientation
704   VISU::Orientation anOrientation = aPlane->GetOrientation();
705
706   // Rotations
707   double aRot[2] = {aPlane->myAngle[0], aPlane->myAngle[1]};
708
709   // Set plane parameters in the dialog
710   myIsSelectPlane = true;
711   setDistance(aPlane->GetDistance());
712   setRotation(aRot[0], aRot[1]);
713   int item = 0;
714   switch (anOrientation) {
715   case VISU::XY: item = 0; break;
716   case VISU::YZ: item = 1; break;
717   case VISU::ZX: item = 2; break;
718   }
719   ComboBoxOrientation->setCurrentIndex(item);
720
721   bool isIJK = (TabPane->currentWidget() == WidgetIJKTab);
722   if (isIJK)
723     setIJKByNonStructured();
724   else
725     onSelectOrientation(item);
726
727   myIsSelectPlane = false;
728 }
729
730 //=================================================================================
731 // function : ClickOnNew()
732 // purpose  :
733 //=================================================================================
734 void VisuGUI_ClippingDlg::ClickOnNew()
735 {
736   VISU::TSelectionInfo aSelectionInfo = VISU::GetSelectedObjects(myVisuGUI);
737   if(aSelectionInfo.empty())
738     return;
739
740   const VISU::TSelectionItem& aSelectionItem = aSelectionInfo[0];
741   if(!aSelectionItem.myObjectInfo.myBase) 
742     return;
743
744   SetCurrentPlaneParam();
745   
746   if (!myPrs3d)
747     return;
748
749   if (SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI)) {
750     OrientedPlane* aPlane = OrientedPlane::New(aViewWindow);
751     VISU::TVTKPlane aTVTKPlane(aPlane);
752     myPlanes.push_back(aTVTKPlane);
753
754     CORBA::Float anOffset[3];
755     myPrs3d->GetOffset(anOffset[0],anOffset[1],anOffset[2]);
756     aTVTKPlane->myActor->SetPosition(anOffset[0],anOffset[1],anOffset[2]);
757
758     if (PreviewCheckBox->isChecked())
759       aTVTKPlane->myActor->VisibilityOn();
760
761     Sinchronize();
762     SetCurrentPlaneParam();
763   }
764 }
765
766 //=================================================================================
767 // function : ClickOnDelete()
768 // purpose  :
769 //=================================================================================
770 void VisuGUI_ClippingDlg::ClickOnDelete()
771 {
772   if (!myPrs3d || myPlanes.empty())
773     return;
774
775   int aPlaneIndex = ComboBoxPlanes->currentIndex();
776
777   VISU::TPlanes::iterator anIter = myPlanes.begin() + aPlaneIndex;
778   anIter->GetPointer()->myActor->SetVisibility(false);
779   myPlanes.erase(anIter);
780
781   if(AutoApplyCheckBox->isChecked())
782     ClickOnApply();
783
784   Sinchronize();
785   if (SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI))
786     VISU::RenderViewWindow(aViewWindow);
787 }
788
789 //=================================================================================
790 // function : onSelectOrientation()
791 // purpose  :
792 //=================================================================================
793 void VisuGUI_ClippingDlg::onSelectOrientation(int theItem)
794 {
795   if (myPlanes.empty())
796     return;
797
798   if      (theItem == 0) {
799     TextLabelRot1->setText(tr("LBL_ROTATION_YZ"));
800     TextLabelRot2->setText(tr("LBL_ROTATION_XZ"));
801   }
802   else if (theItem == 1) {
803     TextLabelRot1->setText(tr("LBL_ROTATION_ZX"));
804     TextLabelRot2->setText(tr("LBL_ROTATION_YX"));
805   }
806   else if (theItem == 2) {
807     TextLabelRot1->setText(tr("LBL_ROTATION_XY"));
808     TextLabelRot2->setText(tr("LBL_ROTATION_ZY"));
809   }
810
811   if((QComboBox*)sender() == ComboBoxOrientation)
812     SetCurrentPlaneParam();
813 }
814
815 //=================================================================================
816 // function : Sinchronize()
817 // purpose  : update control values according to plane selection
818 //=================================================================================
819 void VisuGUI_ClippingDlg::Sinchronize()
820 {
821   int aNbPlanes = myPlanes.size();
822   ComboBoxPlanes->clear();
823
824   QString aName;
825   for (int i = 1; i<=aNbPlanes; i++) {
826     aName = QString(tr("PLANES_COMBO_ITEM_i")).arg(i);
827     ComboBoxPlanes->addItem(aName);
828   }
829
830   int aPos = ComboBoxPlanes->count() - 1;
831   ComboBoxPlanes->setCurrentIndex(aPos);
832
833   bool anIsControlsEnable = (aPos >= 0);
834   if (anIsControlsEnable) {
835     onSelectPlane(aPos);
836   } else {
837     ComboBoxPlanes->addItem(tr("PLANES_COMBO_ITEM_no"));
838     SpinBoxRot1->setValue(0.0);
839     SpinBoxRot2->setValue(0.0);
840     SpinBoxDistance->setValue(0.5);
841   }
842
843   buttonDelete           ->setEnabled(anIsControlsEnable);
844   //buttonApply            ->setEnabled(anIsControlsEnable);
845   //  PreviewCheckBox        ->setEnabled(anIsControlsEnable);
846   //  AutoApplyCheckBox      ->setEnabled(anIsControlsEnable);
847
848   ComboBoxOrientation    ->setEnabled(anIsControlsEnable);
849   SpinBoxDistance        ->setEnabled(anIsControlsEnable);
850   SpinBoxRot1            ->setEnabled(anIsControlsEnable);
851   SpinBoxRot2            ->setEnabled(anIsControlsEnable);
852
853   GroupBoxIJKAxis        ->setEnabled(anIsControlsEnable);
854   SpinBoxIJKIndex        ->setEnabled(anIsControlsEnable);
855   CheckBoxIJKPlaneReverse->setEnabled(anIsControlsEnable);
856   //ENK: 23.11.2006 - PAL13176 - EDF228 VISU : Enhancement of structured datas processing
857   if ( myPrs3d ) {
858     VISU_PipeLine* aPipeLine = myPrs3d->GetPipeLine();
859     VISU::PIDMapper anIDMapper = aPipeLine->GetIDMapper();
860     if ( anIDMapper->IsStructured() ) {
861       VISU::TStructuredId aStructuredId = anIDMapper->GetStructure();
862       ButtonGroupIJKAxis->button(0)->setEnabled( aStructuredId[0] >= 0 );
863       ButtonGroupIJKAxis->button(1)->setEnabled( aStructuredId[1] >= 0 );
864       ButtonGroupIJKAxis->button(2)->setEnabled( aStructuredId[2] >= 0 );
865     }
866   }
867   //ENK: 23.11.2006
868 }
869
870 //=================================================================================
871 // function : setRotation()
872 // purpose  :
873 //=================================================================================
874 void VisuGUI_ClippingDlg::setRotation(const double theRot1, const double theRot2)
875 {
876   SpinBoxRot1->setValue(theRot1);
877   SpinBoxRot2->setValue(theRot2);
878 }
879
880 //=================================================================================
881 // function : SetCurrentPlaneParam()
882 // purpose  :
883 //=================================================================================
884 void VisuGUI_ClippingDlg::SetCurrentPlaneParam()
885 {
886   if (myPlanes.empty() || myIsSelectPlane)
887     return;
888
889   int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
890
891   OrientedPlane* aPlane = myPlanes[aCurPlaneIndex].GetPointer();
892
893   vtkFloatingPointType aNormal[3];
894   VISU::Orientation anOrientation;
895   vtkFloatingPointType aDir[3][3] = {{0, 0, 0}, {0, 0, 0}};
896   {
897     static double aCoeff = vtkMath::Pi()/180.0;
898
899     vtkFloatingPointType aRot[2] = {getRotation1(), getRotation2()};
900     aPlane->myAngle[0] = aRot[0];
901     aPlane->myAngle[1] = aRot[1];
902
903     vtkFloatingPointType anU[2] = {cos(aCoeff*aRot[0]), cos(aCoeff*aRot[1])};
904     vtkFloatingPointType aV[2] = {sqrt(1.0-anU[0]*anU[0]), sqrt(1.0-anU[1]*anU[1])};
905     aV[0] = aRot[0] > 0? aV[0]: -aV[0];
906     aV[1] = aRot[1] > 0? aV[1]: -aV[1];
907
908     switch (ComboBoxOrientation->currentIndex()) {
909     case 0:
910       anOrientation = VISU::XY;
911
912       aDir[0][1] = anU[0];
913       aDir[0][2] = aV[0];
914
915       aDir[1][0] = anU[1];
916       aDir[1][2] = aV[1];
917
918       break;
919     case 1:
920       anOrientation = VISU::YZ;
921
922       aDir[0][2] = anU[0];
923       aDir[0][0] = aV[0];
924
925       aDir[1][1] = anU[1];
926       aDir[1][0] = aV[1];
927
928       break;
929     case 2:
930       anOrientation = VISU::ZX;
931
932       aDir[0][0] = anU[0];
933       aDir[0][1] = aV[0];
934
935       aDir[1][2] = anU[1];
936       aDir[1][1] = aV[1];
937
938       break;
939     }
940
941     vtkMath::Cross(aDir[1],aDir[0],aNormal);
942     vtkMath::Normalize(aNormal);
943     vtkMath::Cross(aNormal,aDir[1],aDir[0]);
944   }
945
946   aPlane->SetOrientation(anOrientation);
947   aPlane->SetDistance(getDistance());
948
949   myPrs3d->SetPlaneParam(aNormal, 1. - getDistance(), aPlane);
950
951   vtkDataSet* aDataSet = myPrs3d->GetInput();
952   vtkFloatingPointType *aPnt = aDataSet->GetCenter();
953
954   vtkFloatingPointType* anOrigin = aPlane->GetOrigin();
955   vtkFloatingPointType aDel = aDataSet->GetLength()/2.0;
956
957   vtkFloatingPointType aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel},
958                                        {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}};
959   vtkFloatingPointType aParam, aPnt0[3], aPnt1[3], aPnt2[3];
960
961   vtkFloatingPointType aPnt01[3] = {aPnt[0] - aDelta[0][0] - aDelta[1][0],
962                                     aPnt[1] - aDelta[0][1] - aDelta[1][1],
963                                     aPnt[2] - aDelta[0][2] - aDelta[1][2]};
964   vtkFloatingPointType aPnt02[3] = {aPnt01[0] + aNormal[0],
965                                     aPnt01[1] + aNormal[1],
966                                     aPnt01[2] + aNormal[2]};
967   vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0);
968
969   vtkFloatingPointType aPnt11[3] = {aPnt[0] - aDelta[0][0] + aDelta[1][0],
970                                     aPnt[1] - aDelta[0][1] + aDelta[1][1],
971                                     aPnt[2] - aDelta[0][2] + aDelta[1][2]};
972   vtkFloatingPointType aPnt12[3] = {aPnt11[0] + aNormal[0],
973                                     aPnt11[1] + aNormal[1],
974                                     aPnt11[2] + aNormal[2]};
975   vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1);
976
977   vtkFloatingPointType aPnt21[3] = {aPnt[0] + aDelta[0][0] - aDelta[1][0],
978                                     aPnt[1] + aDelta[0][1] - aDelta[1][1],
979                                     aPnt[2] + aDelta[0][2] - aDelta[1][2]};
980   vtkFloatingPointType aPnt22[3] = {aPnt21[0] + aNormal[0],
981                                     aPnt21[1] + aNormal[1],
982                                     aPnt21[2] + aNormal[2]};
983   vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2);
984
985   vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource;
986   aPlaneSource->SetNormal(aNormal[0],aNormal[1],aNormal[2]);
987   aPlaneSource->SetOrigin(aPnt0[0],aPnt0[1],aPnt0[2]);
988   aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]);
989   aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]);
990
991   if (AutoApplyCheckBox->isChecked())
992     ClickOnApply();
993
994   if (SVTK_ViewWindow* vw = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI))
995     VISU::RenderViewWindow(vw);
996 }
997
998 //=================================================================================
999 // function : onTabChanged
1000 // purpose  :
1001 //=================================================================================
1002 void VisuGUI_ClippingDlg::onTabChanged(QWidget* newTab)
1003 {
1004   if (newTab == WidgetIJKTab) // IJK
1005     setIJKByNonStructured();
1006   else {
1007     // set correct labels of rotation spin boxes
1008     onSelectOrientation(ComboBoxOrientation->currentIndex());
1009   }
1010 }
1011
1012 //=================================================================================
1013 // function : SetCurrentPlaneIJKParam
1014 // purpose  : set non structured parameters by IJK parameters
1015 //=================================================================================
1016 void VisuGUI_ClippingDlg::SetCurrentPlaneIJKParam()
1017 {
1018   if (myPlanes.empty() || myIsSelectPlane || !WidgetIJKTab->isEnabled())
1019     return;
1020
1021   VISU::Result_i* result = myPrs3d ? myPrs3d->GetCResult() : 0;
1022   if (!result)
1023     return;
1024
1025   // get axis data
1026   int i, axId = ButtonGroupIJKAxis->id (ButtonGroupIJKAxis->checkedButton());
1027   VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) axId;
1028   gp_Dir dir;
1029   CORBA::String_var aMeshName = myPrs3d->GetMeshName();
1030   const vector<vtkFloatingPointType> * values =
1031     result->GetAxisInfo(aMeshName.in(), axis, dir);
1032   if (!values)
1033     return;
1034
1035   // find distance;
1036   int index = SpinBoxIJKIndex->value();
1037   vtkFloatingPointType distance = 0;
1038   if (index < values->size())
1039     distance = (*values)[ index ];
1040
1041   // find id of axis closest to dir
1042   // 0  || X-Y - axis Z
1043   // 1  || Y-Z - azis X
1044   // 2  || Z-X - axiz Y
1045   double cos[3] = { gp::DZ() * dir, gp::DX() * dir, gp::DY() * dir };
1046   double maxCos = 0;
1047   for (i = 0; i < 3; ++i) {
1048     if (Abs(cos[ i ]) > Abs (maxCos)) {
1049       maxCos = cos[ i ];
1050       axId = i;
1051     }
1052   }
1053   // find rotation angles
1054   vtkFloatingPointType angle[2];
1055   int rotId[2] = {
1056     (axId == 0) ? 2 : axId - 1,
1057     (axId == 2) ? 0 : axId + 1
1058     };
1059   static double aCoeff = 180.0/vtkMath::Pi();
1060   for (i = 0; i < 2; ++i) {
1061     vtkFloatingPointType cosin = cos[ rotId[ i ]];
1062 //     if (maxCos < 0)
1063 //       cosin = -cosin;
1064     angle[ i ] = asin(cosin) * aCoeff;
1065 //     if (maxCos < 0)
1066 //       angle[ i ] += 180. * (angle[ i ] < 0 ? 1. : -1.);
1067   }
1068   if (CheckBoxIJKPlaneReverse->isChecked()) {
1069     angle[ 0 ] += 180. * (angle[ 0 ] < 0 ? 1. : -1.);
1070     distance = 1. - distance;
1071   }
1072 //   if (maxCos < 0)
1073 //     distance = 1. - distance;
1074
1075   // set paramerets
1076   myIsSelectPlane = true;
1077   ComboBoxOrientation->setCurrentIndex(axId);
1078   setRotation(-angle[0], -angle[1]);
1079   setDistance(distance);
1080   myIsSelectPlane = false;
1081
1082   SetCurrentPlaneParam();
1083 }
1084
1085 //=================================================================================
1086 // function : setIJKByNonStructured
1087 // purpose  : convert current non structured parameters to structured ones
1088 //=================================================================================
1089 void VisuGUI_ClippingDlg::setIJKByNonStructured()
1090 {
1091   if (!myPrs3d || myPlanes.empty() || !myPrs3d->GetCResult())
1092     return;
1093
1094   // get plane normal
1095   int planeIndex = ComboBoxPlanes->currentIndex();
1096   OrientedPlane* plane = myPlanes[ planeIndex ].GetPointer();
1097   vtkPlaneSource* planeSource = plane->myPlaneSource;
1098   vtkFloatingPointType * planeNormal = planeSource->GetNormal();
1099   gp_Dir normal(planeNormal[0], planeNormal[1], planeNormal[2]);
1100
1101   // find a grid axis most co-directed with plane normal
1102   // and cartesian axis most co-directed with plane normal
1103   int i, maxAx = 0, gridAxId = 0;
1104   gp_Dir dir, gridDir;
1105   double maxDot = 0;
1106   const vector<vtkFloatingPointType> *curValues, *values = 0;
1107   VISU::Result_i* result = myPrs3d->GetCResult();
1108   int aNbAxes = 3;
1109   VISU_PipeLine* aPipeLine = myPrs3d->GetPipeLine();
1110   VISU::PIDMapper anIDMapper = aPipeLine->GetIDMapper();
1111   if ( anIDMapper->IsStructured() && !anIDMapper->myIsPolarType )
1112     aNbAxes = anIDMapper->GetStructureDim();
1113   for (i = 0; i < aNbAxes; ++i) {
1114     VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) i;
1115     CORBA::String_var aMeshName = myPrs3d->GetMeshName();
1116     curValues = result->GetAxisInfo(aMeshName.in(), axis, dir);
1117     if (curValues) {
1118       double dot = normal * dir;
1119       //ENK: 23.11.2006 - PAL13176
1120       if(i==0){
1121         maxDot = dot;
1122         gridDir = dir;
1123         values = curValues;
1124         gridAxId = i;
1125       } else if (Abs(dot) >= Abs(maxDot)) {
1126         maxDot = dot;
1127         gridDir = dir;
1128         values = curValues;
1129         gridAxId = i;
1130       }
1131       //ENK: 23.11.2006
1132     }
1133     if (Abs (planeNormal[ maxAx ]) < Abs (planeNormal[ i ]))
1134       maxAx = i;
1135   }
1136   gp_XYZ axDir(0,0,0);
1137   axDir.SetCoord(maxAx + 1, 1.);
1138
1139   // find index value
1140   double v = SpinBoxDistance->value();
1141   // reverse value?
1142 //   bool reverse = (normal * axDir < 0); // normal and axis are opposite
1143 //   if (gridDir * axDir < 0) // grid dir and axis are opposite
1144 //     reverse = !reverse;
1145 //   if (reverse)
1146 //     v = 1. - v;
1147   for (i = 0; i < values->size(); ++i)
1148     if ((*values)[ i ] > v)
1149       break;
1150   if (i == values->size())
1151     --i;
1152   if (i != 0 && (*values)[ i ] - v > v - (*values)[ i - 1])
1153     --i;
1154
1155   // set control values
1156   myIsSelectPlane = true;
1157   CheckBoxIJKPlaneReverse->setChecked(normal * axDir < 0);
1158   SpinBoxIJKIndex->setValue(i);
1159   ButtonGroupIJKAxis->button(gridAxId)->setChecked( true );
1160   onIJKAxisChanged(gridAxId); // update label and range of index
1161   myIsSelectPlane = false;
1162
1163   SetCurrentPlaneIJKParam();
1164 }
1165
1166 //=================================================================================
1167 // function : isStructured
1168 // purpose  : return true if mesh is structured
1169 //=================================================================================
1170 bool VisuGUI_ClippingDlg::isStructured() const
1171 {
1172   VISU::Result_i* result = myPrs3d ? myPrs3d->GetCResult() : 0;
1173   if (result) {
1174     gp_Dir dir;
1175     return result->GetAxisInfo(myPrs3d->GetCMeshName(),
1176                                VISU::Result_i::AXIS_X,
1177                                dir);
1178   }
1179   return false;
1180 }
1181
1182 //=================================================================================
1183 // function : onIJKAxisChanged
1184 // purpose  : update Index range and call SetCurrentPlaneParam()
1185 //=================================================================================
1186 void VisuGUI_ClippingDlg::onIJKAxisChanged(int axisId)
1187 {
1188   // set index range
1189   int maxIndex = 0;
1190   VISU::Result_i* result = myPrs3d ? myPrs3d->GetCResult() : 0;
1191   if (result) {
1192     VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) axisId;
1193     gp_Dir dir;
1194     CORBA::String_var aMeshName = myPrs3d->GetMeshName();
1195     const vector<vtkFloatingPointType> * indices = result->GetAxisInfo(aMeshName.in(),
1196                                                                        axis, dir);
1197     if (indices)
1198       maxIndex = indices->size() - 1;
1199   }
1200   QString text = tr("LBL_IJK_INDEX_TO_arg").arg(maxIndex);
1201   TextLabelIJKIndex->setText(text);
1202   SpinBoxIJKIndex->setRange(0, maxIndex);
1203
1204   if (SpinBoxIJKIndex->value() > maxIndex)
1205     SpinBoxIJKIndex->setValue(0);
1206
1207   SetCurrentPlaneIJKParam();
1208 }
1209
1210 //=================================================================================
1211 // function : OnPreviewToggle()
1212 // purpose  :
1213 //=================================================================================
1214 void VisuGUI_ClippingDlg::OnPreviewToggle (bool theIsToggled)
1215 {
1216   std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(theIsToggled));
1217   if (SVTK_ViewWindow* vw = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI))
1218     VISU::RenderViewWindow(vw);
1219 }
1220
1221
1222 //=================================================================================
1223 // function : keyPressEvent()
1224 // purpose  :
1225 //=================================================================================
1226 void VisuGUI_ClippingDlg::keyPressEvent( QKeyEvent* e )
1227 {
1228   QDialog::keyPressEvent( e );
1229   if ( e->isAccepted() )
1230     return;
1231
1232   if ( e->key() == Qt::Key_F1 )
1233     {
1234       e->accept();
1235       ClickOnHelp();
1236     }
1237 }
1238
1239 void VisuGUI_ClippingDlg::SetPrs3d(VISU::Prs3d_i* thePrs)
1240 {
1241   if(thePrs != myPrs3d){
1242     if(myPrs3d)
1243       myPrs3d->Destroy();
1244     if(thePrs)
1245       thePrs->Register();
1246     myPrs3d = thePrs;
1247   } else 
1248     return;
1249 }
1250
1251
1252 void VisuGUI_ClippingDlg::removeAllClippingPlanes(VISU::Prs3d_i* thePrs)
1253 {
1254   for (int i = thePrs->GetNumberOfClippingPlanes() - 1; i >= 0 ; i--) {
1255     OrientedPlane* aPlane = dynamic_cast<OrientedPlane*>(thePrs->GetClippingPlane(i));
1256     if (aPlane) 
1257       thePrs->RemoveClippingPlane(i);
1258   }
1259 }
1260
1261