1 // VISU VISUGUI : GUI of VISU component
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
24 // File : VisuGUI_Plot3DDlg.cxx
25 // Author : Laurent CORNABE & Hubert ROLLAND
29 #include "VisuGUI_Plot3DDlg.h"
32 #include "VisuGUI_Tools.h"
33 #include "VisuGUI_ViewTools.h"
34 #include "VisuGUI_InputPane.h"
36 #include "VISU_ColoredPrs3dFactory.hh"
37 #include "VISU_ViewManager_i.hh"
38 #include "VISU_Plot3DPL.hxx"
40 #include "SVTK_ViewWindow.h"
42 #include "SALOME_Actor.h"
43 #include "SUIT_Desktop.h"
44 #include "SUIT_Session.h"
45 #include "SUIT_MessageBox.h"
46 #include "SUIT_ResourceMgr.h"
47 #include "LightApp_Application.h"
49 #include "QtxDblSpinBox.h"
52 #include <qvalidator.h>
53 #include <qtabwidget.h>
54 #include <qradiobutton.h>
56 #include <qcheckbox.h>
58 #include <qpushbutton.h>
60 #include <vtkUnstructuredGrid.h>
61 #include <vtkDataSetMapper.h>
62 #include <vtkRenderer.h>
63 #include <vtkPlaneSource.h>
64 #include <vtkPolyData.h>
69 #define SURFACE_PRS_ID 0
70 #define CONTOUR_PRS_ID 1
72 //=======================================================================
73 //function : renderViewFrame
75 //=======================================================================
76 static void renderViewFrame (SVTK_ViewWindow* vw)
79 vw->getRenderer()->ResetCameraClippingRange();
84 //=======================================================================
86 //purpose : actor of plane preview
87 //=======================================================================
88 class TPlane : public SALOME_Actor
90 vtkFloatingPointType mySize;
91 vtkDataSetMapper* myMapper;
92 vtkPlaneSource* myPlaneSource;
96 TPlane(vtkFloatingPointType planeSize): mySize(planeSize)
100 // set plane parameters
101 void Set(vtkFloatingPointType origin[3], vtkFloatingPointType normal[3])
103 vtkFloatingPointType point2[3], point1[3];
104 vtkMath::Perpendiculars(normal, point1, point2, 0.);
105 for (int i = 0; i < 3; ++i) {
106 point1[ i ] = point1[ i ] * mySize + origin[ i ];
107 point2[ i ] = point2[ i ] * mySize + origin[ i ];
109 myPlaneSource->SetOrigin(origin);
110 myPlaneSource->SetPoint1(point1);
111 myPlaneSource->SetPoint2(point2);
112 myPlaneSource->SetCenter(origin);
114 vtkTypeMacro(TPlane,SALOME_Actor);
118 myPlaneSource = vtkPlaneSource::New();
119 myMapper = vtkDataSetMapper::New();
120 myMapper->SetInput(myPlaneSource->GetOutput());
129 myMapper->RemoveAllInputs();
131 // commented: porting to vtk 5.0
132 //myPlaneSource->UnRegisterAllOutputs();
133 myPlaneSource->Delete();
136 TPlane(const TPlane&);
137 void operator=(const TPlane&);
140 //=======================================================================
141 //function : VisuGUI_Plot3DPane
143 //=======================================================================
144 VisuGUI_Plot3DPane::VisuGUI_Plot3DPane (QWidget* parent)
145 : QVBox(parent), myInitFromPrs(false), myPreviewActor(NULL),
146 myViewWindow(VISU::GetActiveViewWindow<SVTK_ViewWindow>()), myPrs(NULL), myPipeCopy(NULL)
148 layout()->setAlignment(Qt::AlignTop);
153 GBOrientation = new QButtonGroup (tr("Orientation"), this, "GBOrientation");
154 GBOrientation->setTitle(tr("ORIENTATION"));
155 GBOrientation->setColumnLayout(0, Qt::Vertical);
156 GBOrientation->layout()->setSpacing(0);
157 GBOrientation->layout()->setMargin(0);
158 QGridLayout* BGOrientationLayout = new QGridLayout (GBOrientation->layout());
159 BGOrientationLayout->setAlignment(Qt::AlignTop);
160 BGOrientationLayout->setSpacing(6);
161 BGOrientationLayout->setMargin(11);
163 QRadioButton *RBxy, *RByz, *RBzx;
164 RBxy = new QRadioButton (tr("// X-Y"), GBOrientation, "RBxy");
165 RByz = new QRadioButton (tr("// Y-Z"), GBOrientation, "RByz");
166 RBzx = new QRadioButton (tr("// Z-X"), GBOrientation, "RBzx");
167 BGOrientationLayout->addWidget(RBxy, 0, 0);
168 BGOrientationLayout->addWidget(RByz, 0, 1);
169 BGOrientationLayout->addWidget(RBzx, 0, 2);
173 QGroupBox* GBrot = new QGroupBox (tr("ROTATIONS"), this, "GBrot");
174 GBrot->setColumnLayout(0, Qt::Vertical);
175 GBrot->layout()->setSpacing(0);
176 GBrot->layout()->setMargin(0);
177 QGridLayout* GBrotLayout = new QGridLayout (GBrot->layout());
178 GBrotLayout->setAlignment(Qt::AlignTop);
179 GBrotLayout->setSpacing(6);
180 GBrotLayout->setMargin(11);
182 LabelRot1 = new QLabel (tr("ROTATION_X"), GBrot, "LabelRot1");
183 GBrotLayout->addWidget(LabelRot1, 0, 0);
185 Rot1 = new QtxDblSpinBox (-180, 180, 5, GBrot);
186 Rot1->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
187 GBrotLayout->addWidget(Rot1, 0, 1);
189 LabelRot2 = new QLabel (tr("ROTATION_Y"), GBrot, "LabelRot2");
190 GBrotLayout->addWidget(LabelRot2, 1, 0);
192 Rot2 = new QtxDblSpinBox (-180, 180, 5, GBrot);
193 Rot2->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
194 GBrotLayout->addWidget(Rot2, 1, 1);
198 QGroupBox* GBpos = new QGroupBox (tr("POSITION"), this, "GBpos");
199 GBpos->setColumnLayout(0, Qt::Horizontal);
200 GBpos->layout()->setSpacing(0);
201 GBpos->layout()->setMargin(0);
202 QGridLayout* GBposLayout = new QGridLayout (GBpos->layout());
203 GBposLayout->setAlignment(Qt::AlignTop);
204 GBposLayout->setSpacing(6);
205 GBposLayout->setMargin(11);
207 QLabel * valueLabel = new QLabel (tr("POSITION_VALUE"), GBpos, "LabelRot1");
208 GBposLayout->addWidget(valueLabel, 0, 0);
210 PositionSpn = new QtxDblSpinBox (0, 1, 0.1, GBpos);
211 GBposLayout->addWidget(PositionSpn, 0, 1);
213 RelativeChkB = new QCheckBox (tr("RELATIVE"), GBpos, "RelativeChkB");
214 RelativeChkB->setChecked(true);
215 GBposLayout->addWidget(RelativeChkB, 0, 2);
217 // Scale, Presentation type, Nb Contours, Preview
219 QFrame* bottomFrame = new QFrame (this);
220 QGridLayout* bottomLayout = new QGridLayout (bottomFrame);
221 bottomLayout->setAlignment(Qt::AlignTop);
222 bottomLayout->setSpacing(11);
223 bottomLayout->setMargin(0);
225 QLabel* scaleLabel = new QLabel (tr("SCALE"), bottomFrame);
226 ScaleSpn = new QtxDblSpinBox (-1.e6, 1.e6, 0.1, bottomFrame);
228 GBPrsType = new QHButtonGroup (tr("PRESENTATION_TYPE"), bottomFrame);
229 new QRadioButton (tr("SURFACE"), GBPrsType);
230 new QRadioButton (tr("CONTOUR"), GBPrsType);
232 QLabel* nbContLabel = new QLabel (tr("NUMBER_CONTOURS"), bottomFrame);
233 NbContoursSpn = new QSpinBox (1, 999, 1, bottomFrame, "NbContoursSpn");
235 PreviewChkB = new QCheckBox (tr("PREVIEW"), bottomFrame);
236 PreviewChkB->setChecked(false);
238 bottomLayout->addWidget(scaleLabel, 0, 0);
239 bottomLayout->addWidget(ScaleSpn, 0, 1);
240 bottomLayout->addMultiCellWidget(GBPrsType, 1, 1, 0, 1);
241 bottomLayout->addWidget(nbContLabel, 2, 0);
242 bottomLayout->addWidget(NbContoursSpn, 2, 1);
243 bottomLayout->addWidget(PreviewChkB, 3, 0);
245 // signals and slots connections
246 connect(GBOrientation, SIGNAL(clicked(int)), this, SLOT(orientationChanged(int)));
247 connect(Rot1, SIGNAL(valueChanged(double)), this, SLOT(updatePreview()));
248 connect(Rot2, SIGNAL(valueChanged(double)), this, SLOT(updatePreview()));
249 connect(PositionSpn, SIGNAL(valueChanged(double)), this, SLOT(onPositionSpn()));
250 connect(RelativeChkB, SIGNAL(toggled(bool)), this, SLOT(onRelativePos(bool)));
251 connect(GBPrsType, SIGNAL(clicked(int)), this, SLOT(onPrsType(int)));
252 connect(PreviewChkB, SIGNAL(toggled(bool)), this, SLOT(updatePreview()));
255 //=======================================================================
256 //function : destructor
258 //=======================================================================
259 VisuGUI_Plot3DPane::~VisuGUI_Plot3DPane()
262 //=======================================================================
263 //function : storePrsParams
264 //purpose : create a copy of Prs parameters and then store current
265 // control values into the Prs
266 //=======================================================================
267 void VisuGUI_Plot3DPane::storePrsParams()
270 myPipeCopy = VISU_Plot3DPL::New();
272 myPipeCopy->ShallowCopy(myPrs->GetPipeLine(), true);
273 storeToPrsObject(myPrs);
277 //=======================================================================
278 //function : restorePrsParams
279 //purpose : restore Prs parameters from the copy
280 //=======================================================================
281 void VisuGUI_Plot3DPane::restorePrsParams()
284 myPipeCopy = VISU_Plot3DPL::New();
286 myPrs->GetPipeLine()->ShallowCopy(myPipeCopy, false);
289 //=======================================================================
290 //function : onPositionSpn
291 //purpose : update absolute position range
292 //=======================================================================
293 void VisuGUI_Plot3DPane::onPositionSpn()
295 if (myPrs && !RelativeChkB->isChecked()) {
296 vtkFloatingPointType minPos, maxPos;
298 myPrs->GetSpecificPL()->GetMinMaxPosition(minPos, maxPos);
300 if (minPos > PositionSpn->value())
301 minPos = PositionSpn->value();
302 if (maxPos < PositionSpn->value())
303 maxPos = PositionSpn->value();
304 PositionSpn->setRange(minPos, maxPos);
309 //=======================================================================
310 //function : orientationChanged
311 //purpose : update rotation labels and preview
312 //=======================================================================
313 void VisuGUI_Plot3DPane::orientationChanged(int Id)
315 if (Id == 0) { // RBxy->isChecked()
316 LabelRot1->setText(tr("ROTATION_X"));
317 LabelRot2->setText(tr("ROTATION_Y"));
318 } else if (Id == 1) { // RByz->isChecked()
319 LabelRot1->setText(tr("ROTATION_Y"));
320 LabelRot2->setText(tr("ROTATION_Z"));
322 LabelRot1->setText(tr("ROTATION_Z"));
323 LabelRot2->setText(tr("ROTATION_X"));
328 //=======================================================================
329 //function : onRelativePos
330 //purpose : update position value and range
331 //=======================================================================
332 void VisuGUI_Plot3DPane::onRelativePos(bool isRelativePos)
334 vtkFloatingPointType minPos = 0., maxPos = 1., pos = PositionSpn->value();
337 myPrs->GetSpecificPL()->GetMinMaxPosition(minPos, maxPos);
339 if (-1e-7 < (maxPos - minPos) && (maxPos - minPos) < 1e-7) {
342 if (isRelativePos) // absolute -> relative
343 pos = (pos - minPos) / (maxPos - minPos);
344 else // relative -> absolute
345 pos = minPos * (1. - pos) + maxPos * pos;
352 PositionSpn->setMinValue(minPos);
353 PositionSpn->setMaxValue(maxPos);
354 PositionSpn->setLineStep((maxPos - minPos) / 10.);
355 PositionSpn->setValue(pos);
358 //=======================================================================
359 //function : onPrsType
361 //=======================================================================
362 void VisuGUI_Plot3DPane::onPrsType(int id)
364 NbContoursSpn->setEnabled(id == CONTOUR_PRS_ID);
367 //=======================================================================
368 //function : updatePreview
370 //=======================================================================
371 void VisuGUI_Plot3DPane::updatePreview()
374 vtkRenderer* aRend = myPreviewActor->GetRenderer();
375 vtkRenderWindow* aWnd = aRend->GetRenderWindow();
378 if (myInitFromPrs || !myPrs || !myViewWindow)
381 if (PreviewChkB->isChecked()) // place preview plane
383 // get plane preview actor
384 TPlane* planePreview = (TPlane*) myPreviewActor;
386 myPreviewActor = planePreview = new TPlane(myPrs->GetInput()->GetLength());
387 myViewWindow->AddActor(planePreview);
388 fitall = !VISU::FindActor(myViewWindow, myPrs);
390 // set plane parameters corresponding to control values
392 vtkFloatingPointType normal[3], origin[3];
393 myPrs->GetSpecificPL()->GetBasePlane(origin, normal, true);
394 planePreview->Set(origin, normal);
398 myPreviewActor->SetVisibility(PreviewChkB->isChecked());
400 renderViewFrame(myViewWindow);
403 myPreviewActor->SetInfinitive(false);
404 myViewWindow->onFitAll();
405 myPreviewActor->SetInfinitive(true);
409 //=======================================================================
410 //function : initFromPrsObject
412 //=======================================================================
413 void VisuGUI_Plot3DPane::initFromPrsObject(VISU::Plot3D_i* thePrs)
415 myInitFromPrs = true;
420 switch (thePrs->GetOrientationType()) {
421 case VISU::Plot3D::XY: id = 0; break;
422 case VISU::Plot3D::YZ: id = 1; break;
425 GBOrientation->setButton(id);
426 orientationChanged(id);
429 Rot1->setValue(thePrs->GetRotateX() * 180./PI);
430 Rot2->setValue(thePrs->GetRotateY() * 180./PI);
433 RelativeChkB->setChecked(thePrs->IsPositionRelative());
434 onRelativePos(thePrs->IsPositionRelative()); // update range
435 PositionSpn->setValue(thePrs->GetPlanePosition());
438 ScaleSpn->setValue(thePrs->GetScaleFactor());
441 id = thePrs->GetIsContourPrs() ? CONTOUR_PRS_ID : SURFACE_PRS_ID;
442 GBPrsType->setButton(id);
446 NbContoursSpn->setValue(thePrs->GetNbOfContours());
448 // disable cutting plane controls if the mesh is planar
450 if (thePrs->GetPipeLine()->IsPlanarInput())
452 GBOrientation->setEnabled(false);
453 Rot1 ->setEnabled(false);
454 Rot2 ->setEnabled(false);
455 PositionSpn ->setEnabled(false);
456 RelativeChkB ->setEnabled(false);
457 PreviewChkB ->setEnabled(false);
460 myInitFromPrs = false;
464 //=======================================================================
465 //function : storeToPrsObject
467 //=======================================================================
468 int VisuGUI_Plot3DPane::storeToPrsObject(VISU::Plot3D_i* thePrs)
473 int id = GBOrientation->id (GBOrientation->selected());
474 VISU::Plot3D::Orientation ori;
476 case 0 : ori = VISU::Plot3D::XY; break;
477 case 1 : ori = VISU::Plot3D::YZ; break;
478 default: ori = VISU::Plot3D::ZX;
481 thePrs->SetOrientation(ori, Rot1->value()*PI/180., Rot2->value()*PI/180.);
484 thePrs->SetPlanePosition(PositionSpn->value(), RelativeChkB->isChecked());
487 thePrs->SetScaleFactor(ScaleSpn->value());
490 id = GBPrsType->id (GBPrsType->selected());
491 thePrs->SetContourPrs(id == CONTOUR_PRS_ID);
494 thePrs->SetNbOfContours(NbContoursSpn->value());
499 //=======================================================================
502 //=======================================================================
503 bool VisuGUI_Plot3DPane::check()
505 if(!myPreviewActor) return true;
507 vtkRenderer* aRend = myPreviewActor->GetRenderer();
508 vtkRenderWindow* aWnd = aRend->GetRenderWindow();
510 myPreviewActor->SetVisibility(false);
511 myViewWindow->RemoveActor(myPreviewActor);
512 myPreviewActor->Delete();
519 void VisuGUI_Plot3DPane::setPlane(int theOrientation, double theXRotation, double theYRotation, double thePlanePos)
523 switch (theOrientation) {
524 case VISU::Plot3D::XY: id = 0; break;
525 case VISU::Plot3D::YZ: id = 1; break;
528 GBOrientation->setButton(id);
529 orientationChanged(id);
530 GBOrientation->setEnabled(false);
534 Rot1->setValue(theXRotation * 180./PI);
535 Rot1->setEnabled(false);
536 Rot2->setValue(theYRotation * 180./PI);
537 Rot2->setEnabled(false);
540 RelativeChkB->setChecked(false);
541 onRelativePos(false); // update range
542 PositionSpn->setValue(thePlanePos);
543 RelativeChkB->setEnabled(false);
544 PositionSpn->setEnabled(false);
548 //=======================================================================
549 //function : Constructor
551 //=======================================================================
552 VisuGUI_Plot3DDlg::VisuGUI_Plot3DDlg (SalomeApp_Module* theModule)
553 : VisuGUI_ScalarBarBaseDlg(theModule)
555 setCaption(tr("TITLE"));
556 setSizeGripEnabled(TRUE);
558 QVBoxLayout* TopLayout = new QVBoxLayout(this);
559 TopLayout->setSpacing(6);
560 TopLayout->setMargin(11);
562 myTabBox = new QTabWidget (this);
563 myIsoPane = new VisuGUI_Plot3DPane (this);
564 myIsoPane->setMargin(5);
565 myTabBox->addTab(myIsoPane, tr("PLOT3D_TAB_TITLE"));
566 myInputPane = new VisuGUI_InputPane(VISU::TPLOT3D, theModule, this);
567 myTabBox->addTab(GetScalarPane(), tr("SCALAR_BAR_TAB_TITLE"));
568 myTabBox->addTab(myInputPane, tr("INPUT_TAB_TITLE"));
570 TopLayout->addWidget(myTabBox);
572 QGroupBox* GroupButtons = new QGroupBox (this, "GroupButtons");
573 GroupButtons->setGeometry(QRect(10, 10, 281, 48));
574 GroupButtons->setColumnLayout(0, Qt::Vertical);
575 GroupButtons->layout()->setSpacing(0);
576 GroupButtons->layout()->setMargin(0);
577 QGridLayout* GroupButtonsLayout = new QGridLayout (GroupButtons->layout());
578 GroupButtonsLayout->setAlignment(Qt::AlignTop);
579 GroupButtonsLayout->setSpacing(6);
580 GroupButtonsLayout->setMargin(11);
582 QPushButton* buttonOk = new QPushButton (tr("&OK"), GroupButtons, "buttonOk");
583 buttonOk->setAutoDefault(TRUE);
584 buttonOk->setDefault(TRUE);
585 GroupButtonsLayout->addWidget(buttonOk, 0, 0);
586 GroupButtonsLayout->addItem(new QSpacerItem (5, 5, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 1);
587 QPushButton* buttonCancel = new QPushButton (tr("&Cancel") , GroupButtons, "buttonCancel");
588 buttonCancel->setAutoDefault(TRUE);
589 GroupButtonsLayout->addWidget(buttonCancel, 0, 2);
590 QPushButton* buttonHelp = new QPushButton (tr("&Help") , GroupButtons, "buttonHelp");
591 buttonHelp->setAutoDefault(TRUE);
592 GroupButtonsLayout->addWidget(buttonHelp, 0, 3);
594 TopLayout->addWidget(GroupButtons);
596 // signals and slots connections
597 connect(buttonOk, SIGNAL(clicked()), this, SLOT(accept()));
598 connect(buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
599 connect(buttonHelp, SIGNAL(clicked()), this, SLOT(onHelp()));
602 VisuGUI_Plot3DDlg::~VisuGUI_Plot3DDlg()
605 //=======================================================================
608 //=======================================================================
609 void VisuGUI_Plot3DDlg::accept()
611 if (myIsoPane->check() && GetScalarPane()->check())
612 VisuGUI_ScalarBarBaseDlg::accept();
615 //=======================================================================
618 //=======================================================================
619 void VisuGUI_Plot3DDlg::reject()
621 VisuGUI_ScalarBarBaseDlg::reject();
624 //=======================================================================
625 //function : initFromPrsObject
627 //=======================================================================
628 void VisuGUI_Plot3DDlg::initFromPrsObject (VISU::ColoredPrs3d_i* thePrs,
632 myPrsCopy = VISU::TSameAsFactory<VISU::TPLOT3D>().Create(thePrs, VISU::ColoredPrs3d_i::EDoNotPublish);
634 VisuGUI_ScalarBarBaseDlg::initFromPrsObject(myPrsCopy, theInit);
636 myIsoPane->initFromPrsObject(myPrsCopy);
641 myInputPane->initFromPrsObject( myPrsCopy );
642 myTabBox->setCurrentPage( 0 );
645 //=======================================================================
646 //function : storeToPrsObject
648 //=======================================================================
649 int VisuGUI_Plot3DDlg::storeToPrsObject (VISU::ColoredPrs3d_i* thePrs)
651 if(!myInputPane->check() || !GetScalarPane()->check())
654 int anIsOk = myInputPane->storeToPrsObject( myPrsCopy );
655 anIsOk &= GetScalarPane()->storeToPrsObject( myPrsCopy );
656 anIsOk &= myIsoPane->storeToPrsObject( myPrsCopy );
658 VISU::TSameAsFactory<VISU::TPLOT3D>().Copy(myPrsCopy, thePrs);
663 //=======================================================================
666 //=======================================================================
667 QString VisuGUI_Plot3DDlg::GetContextHelpFilePath()
669 return "plot_3d_page.html";
672 //=======================================================================
673 //function : setPlane
675 //=======================================================================
676 void VisuGUI_Plot3DDlg::setPlane(int theOrientation, double theXRotation, double theYRotation, double thePlanePos)
678 myIsoPane->setPlane(theOrientation, theXRotation, theYRotation, thePlanePos);