Salome HOME
Erase the scalar bar preview after the dialog closing.
[modules/visu.git] / src / VISUGUI / VisuGUI_Plot3DDlg.cxx
1 //  VISU VISUGUI : GUI of VISU component
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
21 //
22 //
23 //
24 //  File   : VisuGUI_Plot3DDlg.cxx
25 //  Author : Laurent CORNABE & Hubert ROLLAND
26 //  Module : VISU
27 //  $Header$
28
29 #include "VisuGUI_Plot3DDlg.h"
30
31 #include "VisuGUI.h"
32 #include "VisuGUI_Tools.h"
33
34 #include "VISU_ViewManager_i.hh"
35 #include "VISU_Plot3DPL.hxx"
36
37 #include "SALOME_Actor.h"
38 #include "SVTK_ViewWindow.h"
39 #include "SUIT_Desktop.h"
40
41 #include <qlayout.h>
42 #include <qvalidator.h>
43 #include <qtabwidget.h>
44
45 #include <vtkUnstructuredGrid.h>
46 #include <vtkDataSetMapper.h>
47 #include <vtkRenderer.h>
48 #include <vtkPlaneSource.h>
49 #include <vtkPolyData.h>
50 #include <vtkMath.h>
51
52 using namespace std;
53
54 #define SURFACE_PRS_ID 0
55 #define CONTOUR_PRS_ID 1
56
57 //=======================================================================
58 //function : renderViewFrame
59 //purpose  :
60 //=======================================================================
61 static void renderViewFrame (SVTK_ViewWindow* vw)
62 {
63   if (vw) {
64     vw->getRenderer()->ResetCameraClippingRange();
65     vw->Repaint();
66   }
67 }
68
69 //=======================================================================
70 //class    : TPlane
71 //purpose  : actor of plane preview
72 //=======================================================================
73 class TPlane : public SALOME_Actor
74 {
75   float                mySize;
76   vtkDataSetMapper*    myMapper;
77   vtkPlaneSource*      myPlaneSource;
78
79  public:
80   // constructor
81   TPlane(float planeSize): mySize(planeSize)
82   {
83     Init();
84   }
85   // set plane parameters
86   void Set(float origin[3], float normal[3])
87   {
88     float point2[3], point1[3];
89     vtkMath::Perpendiculars(normal, point1, point2, 0.);
90     for (int i = 0; i < 3; ++i) {
91       point1[ i ] = point1[ i ] * mySize + origin[ i ];
92       point2[ i ] = point2[ i ] * mySize + origin[ i ];
93     }
94     myPlaneSource->SetOrigin(origin);
95     myPlaneSource->SetPoint1(point1);
96     myPlaneSource->SetPoint2(point2);
97     myPlaneSource->SetCenter(origin);
98   }
99   vtkTypeMacro(TPlane,SALOME_Actor);
100
101  protected:
102   void Init() {
103     myPlaneSource = vtkPlaneSource::New();
104     myMapper = vtkDataSetMapper::New();
105     myMapper->SetInput(myPlaneSource->GetOutput());
106     // actor methods
107     VisibilityOff();
108     PickableOff();
109     SetInfinitive(true);
110     SetOpacity(0.85);
111     SetMapper(myMapper);
112   }
113   ~TPlane() {
114     myMapper->RemoveAllInputs();
115     myMapper->Delete();
116     myPlaneSource->UnRegisterAllOutputs();
117     myPlaneSource->Delete();
118   };
119   // Not implemented.
120   TPlane(const TPlane&);
121   void operator=(const TPlane&);
122 };
123
124 //=======================================================================
125 //function : VisuGUI_Plot3DPane
126 //purpose  :
127 //=======================================================================
128 VisuGUI_Plot3DPane::VisuGUI_Plot3DPane (QWidget* parent)
129      : QVBox(parent), myInitFromPrs(false), myPreviewActor(NULL),
130        myViewWindow(VISU::GetViewWindow()), myPrs(NULL), myPipeCopy(NULL)
131 {
132   layout()->setAlignment(Qt::AlignTop);
133   setSpacing(6);
134
135   // Orientation
136
137   GBOrientation = new QButtonGroup (tr("Orientation"), this, "GBOrientation");
138   GBOrientation->setTitle(tr("ORIENTATION"));
139   GBOrientation->setColumnLayout(0, Qt::Vertical);
140   GBOrientation->layout()->setSpacing(0);
141   GBOrientation->layout()->setMargin(0);
142   QGridLayout* BGOrientationLayout = new QGridLayout (GBOrientation->layout());
143   BGOrientationLayout->setAlignment(Qt::AlignTop);
144   BGOrientationLayout->setSpacing(6);
145   BGOrientationLayout->setMargin(11);
146
147   QRadioButton *RBxy, *RByz, *RBzx;
148   RBxy = new QRadioButton (tr("// X-Y"), GBOrientation, "RBxy");
149   RByz = new QRadioButton (tr("// Y-Z"), GBOrientation, "RByz");
150   RBzx = new QRadioButton (tr("// Z-X"), GBOrientation, "RBzx");
151   BGOrientationLayout->addWidget(RBxy, 0, 0);
152   BGOrientationLayout->addWidget(RByz, 0, 1);
153   BGOrientationLayout->addWidget(RBzx, 0, 2);
154
155   // Rotation
156
157   QGroupBox* GBrot = new QGroupBox (tr("ROTATIONS"), this, "GBrot");
158   GBrot->setColumnLayout(0, Qt::Vertical);
159   GBrot->layout()->setSpacing(0);
160   GBrot->layout()->setMargin(0);
161   QGridLayout* GBrotLayout = new QGridLayout (GBrot->layout());
162   GBrotLayout->setAlignment(Qt::AlignTop);
163   GBrotLayout->setSpacing(6);
164   GBrotLayout->setMargin(11);
165   // label 1
166   LabelRot1 = new QLabel (tr("ROTATION_X"), GBrot, "LabelRot1");
167   GBrotLayout->addWidget(LabelRot1, 0, 0);
168   // spin 1
169   Rot1 = new QtxDblSpinBox (-180, 180, 5, GBrot);
170   Rot1->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
171   GBrotLayout->addWidget(Rot1, 0, 1);
172   // label 2
173   LabelRot2 = new QLabel (tr("ROTATION_Y"), GBrot, "LabelRot2");
174   GBrotLayout->addWidget(LabelRot2, 1, 0);
175   // spin 2
176   Rot2 = new QtxDblSpinBox (-180, 180, 5, GBrot);
177   Rot2->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
178   GBrotLayout->addWidget(Rot2, 1, 1);
179
180   // Position
181
182   QGroupBox* GBpos = new QGroupBox (tr("POSITION"), this, "GBpos");
183   GBpos->setColumnLayout(0, Qt::Horizontal);
184   GBpos->layout()->setSpacing(0);
185   GBpos->layout()->setMargin(0);
186   QGridLayout* GBposLayout = new QGridLayout (GBpos->layout());
187   GBposLayout->setAlignment(Qt::AlignTop);
188   GBposLayout->setSpacing(6);
189   GBposLayout->setMargin(11);
190   // value label
191   QLabel * valueLabel = new QLabel (tr("POSITION_VALUE"), GBpos, "LabelRot1");
192   GBposLayout->addWidget(valueLabel, 0, 0);
193   // value spin
194   PositionSpn = new QtxDblSpinBox (0, 1, 0.1, GBpos);
195   GBposLayout->addWidget(PositionSpn, 0, 1);
196   // Relative CheckBox
197   RelativeChkB = new QCheckBox (tr("RELATIVE"), GBpos, "RelativeChkB");
198   RelativeChkB->setChecked(true);
199   GBposLayout->addWidget(RelativeChkB, 0, 2);
200
201   // Scale, Presentation type, Nb Contours, Preview
202
203   QFrame* bottomFrame = new QFrame (this);
204   QGridLayout* bottomLayout = new QGridLayout (bottomFrame);
205   bottomLayout->setAlignment(Qt::AlignTop);
206   bottomLayout->setSpacing(11);
207   bottomLayout->setMargin(0);
208   // scale
209   QLabel* scaleLabel = new QLabel (tr("SCALE"), bottomFrame);
210   ScaleSpn = new QtxDblSpinBox (-1.e6, 1.e6, 0.1, bottomFrame);
211   // Presentation type
212   GBPrsType = new QHButtonGroup (tr("PRESENTATION_TYPE"), bottomFrame);
213   new QRadioButton (tr("SURFACE"), GBPrsType);
214   new QRadioButton (tr("CONTOUR"), GBPrsType);
215   // nb Contours
216   QLabel* nbContLabel = new QLabel (tr("NUMBER_CONTOURS"), bottomFrame);
217   NbContoursSpn = new QSpinBox (1, 999, 1, bottomFrame, "NbContoursSpn");
218   // Preview
219   PreviewChkB = new QCheckBox (tr("PREVIEW"), bottomFrame);
220   PreviewChkB->setChecked(false);
221
222   bottomLayout->addWidget(scaleLabel,    0, 0);
223   bottomLayout->addWidget(ScaleSpn,      0, 1);
224   bottomLayout->addMultiCellWidget(GBPrsType, 1, 1, 0, 1);
225   bottomLayout->addWidget(nbContLabel,   2, 0);
226   bottomLayout->addWidget(NbContoursSpn, 2, 1);
227   bottomLayout->addWidget(PreviewChkB,   3, 0);
228
229   // signals and slots connections
230   connect(GBOrientation, SIGNAL(clicked(int)),         this, SLOT(orientationChanged(int)));
231   connect(Rot1,          SIGNAL(valueChanged(double)), this, SLOT(updatePreview()));
232   connect(Rot2,          SIGNAL(valueChanged(double)), this, SLOT(updatePreview()));
233   connect(PositionSpn,   SIGNAL(valueChanged(double)), this, SLOT(onPositionSpn()));
234   connect(RelativeChkB,  SIGNAL(toggled(bool)),        this, SLOT(onRelativePos(bool)));
235   connect(GBPrsType,     SIGNAL(clicked(int)),         this, SLOT(onPrsType(int)));
236   connect(PreviewChkB,   SIGNAL(toggled(bool)),        this, SLOT(updatePreview()));
237 }
238
239 //=======================================================================
240 //function : destructor
241 //purpose  :
242 //=======================================================================
243 VisuGUI_Plot3DPane::~VisuGUI_Plot3DPane()
244 {
245 }
246
247 //=======================================================================
248 //function : storePrsParams
249 //purpose  : create a copy of Prs parameters and then store current
250 //           control values into the Prs
251 //=======================================================================
252 void VisuGUI_Plot3DPane::storePrsParams()
253 {
254   if (!myPipeCopy)
255     myPipeCopy = VISU_Plot3DPL::New();
256   if (myPrs) {
257     myPipeCopy->ShallowCopy(myPrs->GetPL());
258     storeToPrsObject(myPrs);
259   }
260 }
261
262 //=======================================================================
263 //function : restorePrsParams
264 //purpose  : restore Prs parameters from the copy
265 //=======================================================================
266 void VisuGUI_Plot3DPane::restorePrsParams()
267 {
268   if (!myPipeCopy)
269     myPipeCopy = VISU_Plot3DPL::New();
270   if (myPrs)
271     myPrs->GetPL()->ShallowCopy(myPipeCopy);
272 }
273
274 //=======================================================================
275 //function : onPositionSpn
276 //purpose  : update absolute position range
277 //=======================================================================
278 void VisuGUI_Plot3DPane::onPositionSpn()
279 {
280   if (myPrs && !RelativeChkB->isChecked()) {
281     float minPos, maxPos;
282     storePrsParams();
283     myPrs->GetPlot3DPL()->GetMinMaxPosition(minPos, maxPos);
284     restorePrsParams();
285     if (minPos > PositionSpn->value())
286       minPos = PositionSpn->value();
287     if (maxPos < PositionSpn->value())
288       maxPos = PositionSpn->value();
289     PositionSpn->setRange(minPos, maxPos);
290   }
291   updatePreview();
292 }
293
294 //=======================================================================
295 //function : orientationChanged
296 //purpose  : update rotation labels and preview
297 //=======================================================================
298 void VisuGUI_Plot3DPane::orientationChanged(int Id)
299 {
300   if (Id == 0) { // RBxy->isChecked()
301     LabelRot1->setText(tr("ROTATION_X"));
302     LabelRot2->setText(tr("ROTATION_Y"));
303   } else if (Id == 1) { // RByz->isChecked()
304     LabelRot1->setText(tr("ROTATION_Y"));
305     LabelRot2->setText(tr("ROTATION_Z"));
306   } else {
307     LabelRot1->setText(tr("ROTATION_Z"));
308     LabelRot2->setText(tr("ROTATION_X"));
309   }
310   updatePreview();
311 }
312
313 //=======================================================================
314 //function : onRelativePos
315 //purpose  : update position value and range
316 //=======================================================================
317 void VisuGUI_Plot3DPane::onRelativePos(bool isRelativePos)
318 {
319   float minPos = 0., maxPos = 1., pos = PositionSpn->value();
320   if (myPrs) {
321     storePrsParams();
322     myPrs->GetPlot3DPL()->GetMinMaxPosition(minPos, maxPos);
323     restorePrsParams();
324     if (-1e-7 < (maxPos - minPos) && (maxPos - minPos) < 1e-7) {
325       pos = 0;
326     } else {
327       if (isRelativePos) // absolute -> relative
328         pos = (pos - minPos) / (maxPos - minPos);
329       else  // relative -> absolute
330         pos = minPos * (1. - pos) + maxPos * pos;
331     }
332   }
333   if (isRelativePos) {
334     minPos = 0.;
335     maxPos = 1.;
336   }
337   PositionSpn->setMinValue(minPos);
338   PositionSpn->setMaxValue(maxPos);
339   PositionSpn->setLineStep((maxPos - minPos) / 10.);
340   PositionSpn->setValue(pos);
341 }
342
343 //=======================================================================
344 //function : onPrsType
345 //purpose  :
346 //=======================================================================
347 void VisuGUI_Plot3DPane::onPrsType(int id)
348 {
349   NbContoursSpn->setEnabled(id == CONTOUR_PRS_ID);
350 }
351
352 //=======================================================================
353 //function : updatePreview
354 //purpose  :
355 //=======================================================================
356 void VisuGUI_Plot3DPane::updatePreview()
357 {
358   if (myInitFromPrs || !myPrs || !myViewWindow)
359     return;
360   bool fitall = false;
361   if (PreviewChkB->isChecked()) // place preview plane
362   {
363     // get plane preview actor
364     TPlane* planePreview = (TPlane*) myPreviewActor;
365     if (!planePreview) {
366       myPreviewActor = planePreview = new TPlane(myPrs->GetInput()->GetLength());
367       myViewWindow->AddActor(planePreview);
368       fitall = !VISU::GetActor(myPrs, myViewWindow);
369     }
370     // set plane parameters corresponding to control values
371     storePrsParams();
372     float normal[3], origin[3];
373     myPrs->GetPlot3DPL()->GetBasePlane(origin, normal, true);
374     planePreview->Set(origin, normal);
375     restorePrsParams();
376   }
377   if (myPreviewActor)
378     myPreviewActor->SetVisibility(PreviewChkB->isChecked());
379
380   renderViewFrame(myViewWindow);
381
382   if (fitall) {
383     myPreviewActor->SetInfinitive(false);
384     myViewWindow->onFitAll();
385     myPreviewActor->SetInfinitive(true);
386   }
387 }
388
389 //=======================================================================
390 //function : initFromPrsObject
391 //purpose  :
392 //=======================================================================
393 void VisuGUI_Plot3DPane::initFromPrsObject(VISU::Plot3D_i* thePrs)
394 {
395   myInitFromPrs = true;
396   myPrs = thePrs;
397
398   // orientation
399   int id;
400   switch (thePrs->GetOrientationType()) {
401   case VISU::Plot3D::XY: id = 0; break;
402   case VISU::Plot3D::YZ: id = 1; break;
403   default: id = 2;
404   }
405   GBOrientation->setButton(id);
406   orientationChanged(id);
407
408   // rotation
409   Rot1->setValue(thePrs->GetRotateX() * 180./PI);
410   Rot2->setValue(thePrs->GetRotateY() * 180./PI);
411
412   // position
413   RelativeChkB->setChecked(thePrs->IsPositionRelative());
414   onRelativePos(thePrs->IsPositionRelative()); // update range
415   PositionSpn->setValue(thePrs->GetPlanePosition());
416
417   // scale
418   ScaleSpn->setValue(thePrs->GetScaleFactor());
419
420   // prs type
421   id = thePrs->GetIsContourPrs() ? CONTOUR_PRS_ID : SURFACE_PRS_ID;
422   GBPrsType->setButton(id);
423   onPrsType(id);
424
425   // nb contours
426   NbContoursSpn->setValue(thePrs->GetNbOfContours());
427
428   // disable cutting plane controls if the mesh is planar
429
430   if (thePrs->GetPL()->IsPlanarInput())
431   {
432     GBOrientation->setEnabled(false);
433     Rot1         ->setEnabled(false);
434     Rot2         ->setEnabled(false);
435     PositionSpn  ->setEnabled(false);
436     RelativeChkB ->setEnabled(false);
437     PreviewChkB  ->setEnabled(false);
438   }
439
440   myInitFromPrs = false;
441   updatePreview();
442 }
443
444 //=======================================================================
445 //function : storeToPrsObject
446 //purpose  :
447 //=======================================================================
448 int VisuGUI_Plot3DPane::storeToPrsObject(VISU::Plot3D_i* thePrs)
449 {
450   if (myInitFromPrs)
451     return 0;
452   // orientation
453   int id = GBOrientation->id (GBOrientation->selected());
454   VISU::Plot3D::Orientation ori;
455   switch (id) {
456   case 0 : ori = VISU::Plot3D::XY; break;
457   case 1 : ori = VISU::Plot3D::YZ; break;
458   default: ori = VISU::Plot3D::ZX;
459   }
460   // rotation
461   thePrs->SetOrientation(ori, Rot1->value()*PI/180., Rot2->value()*PI/180.);
462
463   // position
464   thePrs->SetPlanePosition(PositionSpn->value(), RelativeChkB->isChecked());
465
466   // scale
467   thePrs->SetScaleFactor(ScaleSpn->value());
468
469   // prs type
470   id = GBPrsType->id (GBPrsType->selected());
471   thePrs->SetContourPrs(id == CONTOUR_PRS_ID);
472
473   // nb contours
474   thePrs->SetNbOfContours(NbContoursSpn->value());
475
476   return 1;
477 }
478
479 //=======================================================================
480 //function : check
481 //purpose  :
482 //=======================================================================
483 bool VisuGUI_Plot3DPane::check()
484 {
485   if (myPreviewActor && myViewWindow) // erase preview
486   {
487     myPreviewActor->SetVisibility(false);
488     myViewWindow->RemoveActor(myPreviewActor);
489     myPreviewActor->Delete();
490     myPreviewActor = 0;
491   }
492
493   return true;
494 }
495
496 //=======================================================================
497 //function : Constructor
498 //purpose  :
499 //=======================================================================
500 VisuGUI_Plot3DDlg::VisuGUI_Plot3DDlg (SalomeApp_Module* theModule)
501   : QDialog(VISU::GetDesktop(theModule), "VisuGUI_Plot3DDlg", false, WStyle_Customize |
502             WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu)
503 {
504   setCaption(tr("TITLE"));
505   setSizeGripEnabled(TRUE);
506
507   QVBoxLayout* TopLayout = new QVBoxLayout(this);
508   TopLayout->setSpacing(6);
509   TopLayout->setMargin(11);
510
511   QTabWidget* aTabBox = new QTabWidget (this);
512   myIsoPane = new VisuGUI_Plot3DPane (this);
513   myIsoPane->setMargin(5);
514   aTabBox->addTab(myIsoPane, tr("PLOT3D_TAB_TITLE"));
515   myScalarPane = new VisuGUI_ScalarBarPane (this, false);
516   myScalarPane->setMargin(5);
517   aTabBox->addTab(myScalarPane, tr("SCALAR_BAR_TAB_TITLE"));
518
519   TopLayout->addWidget(aTabBox);
520
521   QGroupBox* GroupButtons = new QGroupBox (this, "GroupButtons");
522   GroupButtons->setGeometry(QRect(10, 10, 281, 48));
523   GroupButtons->setColumnLayout(0, Qt::Vertical);
524   GroupButtons->layout()->setSpacing(0);
525   GroupButtons->layout()->setMargin(0);
526   QGridLayout* GroupButtonsLayout = new QGridLayout (GroupButtons->layout());
527   GroupButtonsLayout->setAlignment(Qt::AlignTop);
528   GroupButtonsLayout->setSpacing(6);
529   GroupButtonsLayout->setMargin(11);
530
531   QPushButton* buttonOk = new QPushButton (tr("&OK"), GroupButtons, "buttonOk");
532   buttonOk->setAutoDefault(TRUE);
533   buttonOk->setDefault(TRUE);
534   GroupButtonsLayout->addWidget(buttonOk, 0, 0);
535   GroupButtonsLayout->addItem(new QSpacerItem (5, 5, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 1);
536   QPushButton* buttonCancel = new QPushButton (tr("&Cancel") , GroupButtons, "buttonCancel");
537   buttonCancel->setAutoDefault(TRUE);
538   GroupButtonsLayout->addWidget(buttonCancel, 0, 2);
539
540   TopLayout->addWidget(GroupButtons);
541
542   // signals and slots connections
543   connect(buttonOk,     SIGNAL(clicked()), this, SLOT(accept()));
544   connect(buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
545 }
546
547 //=======================================================================
548 //function : accept
549 //purpose  :
550 //=======================================================================
551 void VisuGUI_Plot3DDlg::accept()
552 {
553   if (myIsoPane->check() && myScalarPane->check())
554     {
555       myScalarPane->deletePreview();
556       QDialog::accept();
557     }
558 }
559
560 //=======================================================================
561 //function : reject
562 //purpose  :
563 //=======================================================================
564 void VisuGUI_Plot3DDlg::reject()
565 {
566   myIsoPane->check(); // hide preview
567   myScalarPane->deletePreview();
568   
569   QDialog::reject();
570 }