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"
35 #include "VISU_ViewManager_i.hh"
36 #include "VISU_Plot3DPL.hxx"
38 #include "SVTK_ViewWindow.h"
40 #include "SALOME_Actor.h"
41 #include "SUIT_Desktop.h"
42 #include "SUIT_Session.h"
43 #include "SUIT_MessageBox.h"
44 #include "SUIT_ResourceMgr.h"
45 #include "LightApp_Application.h"
48 #include <qvalidator.h>
49 #include <qtabwidget.h>
51 #include <vtkUnstructuredGrid.h>
52 #include <vtkDataSetMapper.h>
53 #include <vtkRenderer.h>
54 #include <vtkPlaneSource.h>
55 #include <vtkPolyData.h>
60 #define SURFACE_PRS_ID 0
61 #define CONTOUR_PRS_ID 1
63 //=======================================================================
64 //function : renderViewFrame
66 //=======================================================================
67 static void renderViewFrame (SVTK_ViewWindow* vw)
70 vw->getRenderer()->ResetCameraClippingRange();
75 //=======================================================================
77 //purpose : actor of plane preview
78 //=======================================================================
79 class TPlane : public SALOME_Actor
81 vtkFloatingPointType mySize;
82 vtkDataSetMapper* myMapper;
83 vtkPlaneSource* myPlaneSource;
87 TPlane(vtkFloatingPointType planeSize): mySize(planeSize)
91 // set plane parameters
92 void Set(vtkFloatingPointType origin[3], vtkFloatingPointType normal[3])
94 vtkFloatingPointType point2[3], point1[3];
95 vtkMath::Perpendiculars(normal, point1, point2, 0.);
96 for (int i = 0; i < 3; ++i) {
97 point1[ i ] = point1[ i ] * mySize + origin[ i ];
98 point2[ i ] = point2[ i ] * mySize + origin[ i ];
100 myPlaneSource->SetOrigin(origin);
101 myPlaneSource->SetPoint1(point1);
102 myPlaneSource->SetPoint2(point2);
103 myPlaneSource->SetCenter(origin);
105 vtkTypeMacro(TPlane,SALOME_Actor);
109 myPlaneSource = vtkPlaneSource::New();
110 myMapper = vtkDataSetMapper::New();
111 myMapper->SetInput(myPlaneSource->GetOutput());
120 myMapper->RemoveAllInputs();
122 myPlaneSource->UnRegisterAllOutputs();
123 myPlaneSource->Delete();
126 TPlane(const TPlane&);
127 void operator=(const TPlane&);
130 //=======================================================================
131 //function : VisuGUI_Plot3DPane
133 //=======================================================================
134 VisuGUI_Plot3DPane::VisuGUI_Plot3DPane (QWidget* parent)
135 : QVBox(parent), myInitFromPrs(false), myPreviewActor(NULL),
136 myViewWindow(VISU::GetActiveViewWindow<SVTK_ViewWindow>()), myPrs(NULL), myPipeCopy(NULL)
138 layout()->setAlignment(Qt::AlignTop);
143 GBOrientation = new QButtonGroup (tr("Orientation"), this, "GBOrientation");
144 GBOrientation->setTitle(tr("ORIENTATION"));
145 GBOrientation->setColumnLayout(0, Qt::Vertical);
146 GBOrientation->layout()->setSpacing(0);
147 GBOrientation->layout()->setMargin(0);
148 QGridLayout* BGOrientationLayout = new QGridLayout (GBOrientation->layout());
149 BGOrientationLayout->setAlignment(Qt::AlignTop);
150 BGOrientationLayout->setSpacing(6);
151 BGOrientationLayout->setMargin(11);
153 QRadioButton *RBxy, *RByz, *RBzx;
154 RBxy = new QRadioButton (tr("// X-Y"), GBOrientation, "RBxy");
155 RByz = new QRadioButton (tr("// Y-Z"), GBOrientation, "RByz");
156 RBzx = new QRadioButton (tr("// Z-X"), GBOrientation, "RBzx");
157 BGOrientationLayout->addWidget(RBxy, 0, 0);
158 BGOrientationLayout->addWidget(RByz, 0, 1);
159 BGOrientationLayout->addWidget(RBzx, 0, 2);
163 QGroupBox* GBrot = new QGroupBox (tr("ROTATIONS"), this, "GBrot");
164 GBrot->setColumnLayout(0, Qt::Vertical);
165 GBrot->layout()->setSpacing(0);
166 GBrot->layout()->setMargin(0);
167 QGridLayout* GBrotLayout = new QGridLayout (GBrot->layout());
168 GBrotLayout->setAlignment(Qt::AlignTop);
169 GBrotLayout->setSpacing(6);
170 GBrotLayout->setMargin(11);
172 LabelRot1 = new QLabel (tr("ROTATION_X"), GBrot, "LabelRot1");
173 GBrotLayout->addWidget(LabelRot1, 0, 0);
175 Rot1 = new QtxDblSpinBox (-180, 180, 5, GBrot);
176 Rot1->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
177 GBrotLayout->addWidget(Rot1, 0, 1);
179 LabelRot2 = new QLabel (tr("ROTATION_Y"), GBrot, "LabelRot2");
180 GBrotLayout->addWidget(LabelRot2, 1, 0);
182 Rot2 = new QtxDblSpinBox (-180, 180, 5, GBrot);
183 Rot2->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
184 GBrotLayout->addWidget(Rot2, 1, 1);
188 QGroupBox* GBpos = new QGroupBox (tr("POSITION"), this, "GBpos");
189 GBpos->setColumnLayout(0, Qt::Horizontal);
190 GBpos->layout()->setSpacing(0);
191 GBpos->layout()->setMargin(0);
192 QGridLayout* GBposLayout = new QGridLayout (GBpos->layout());
193 GBposLayout->setAlignment(Qt::AlignTop);
194 GBposLayout->setSpacing(6);
195 GBposLayout->setMargin(11);
197 QLabel * valueLabel = new QLabel (tr("POSITION_VALUE"), GBpos, "LabelRot1");
198 GBposLayout->addWidget(valueLabel, 0, 0);
200 PositionSpn = new QtxDblSpinBox (0, 1, 0.1, GBpos);
201 GBposLayout->addWidget(PositionSpn, 0, 1);
203 RelativeChkB = new QCheckBox (tr("RELATIVE"), GBpos, "RelativeChkB");
204 RelativeChkB->setChecked(true);
205 GBposLayout->addWidget(RelativeChkB, 0, 2);
207 // Scale, Presentation type, Nb Contours, Preview
209 QFrame* bottomFrame = new QFrame (this);
210 QGridLayout* bottomLayout = new QGridLayout (bottomFrame);
211 bottomLayout->setAlignment(Qt::AlignTop);
212 bottomLayout->setSpacing(11);
213 bottomLayout->setMargin(0);
215 QLabel* scaleLabel = new QLabel (tr("SCALE"), bottomFrame);
216 ScaleSpn = new QtxDblSpinBox (-1.e6, 1.e6, 0.1, bottomFrame);
218 GBPrsType = new QHButtonGroup (tr("PRESENTATION_TYPE"), bottomFrame);
219 new QRadioButton (tr("SURFACE"), GBPrsType);
220 new QRadioButton (tr("CONTOUR"), GBPrsType);
222 QLabel* nbContLabel = new QLabel (tr("NUMBER_CONTOURS"), bottomFrame);
223 NbContoursSpn = new QSpinBox (1, 999, 1, bottomFrame, "NbContoursSpn");
225 PreviewChkB = new QCheckBox (tr("PREVIEW"), bottomFrame);
226 PreviewChkB->setChecked(false);
228 bottomLayout->addWidget(scaleLabel, 0, 0);
229 bottomLayout->addWidget(ScaleSpn, 0, 1);
230 bottomLayout->addMultiCellWidget(GBPrsType, 1, 1, 0, 1);
231 bottomLayout->addWidget(nbContLabel, 2, 0);
232 bottomLayout->addWidget(NbContoursSpn, 2, 1);
233 bottomLayout->addWidget(PreviewChkB, 3, 0);
235 // signals and slots connections
236 connect(GBOrientation, SIGNAL(clicked(int)), this, SLOT(orientationChanged(int)));
237 connect(Rot1, SIGNAL(valueChanged(double)), this, SLOT(updatePreview()));
238 connect(Rot2, SIGNAL(valueChanged(double)), this, SLOT(updatePreview()));
239 connect(PositionSpn, SIGNAL(valueChanged(double)), this, SLOT(onPositionSpn()));
240 connect(RelativeChkB, SIGNAL(toggled(bool)), this, SLOT(onRelativePos(bool)));
241 connect(GBPrsType, SIGNAL(clicked(int)), this, SLOT(onPrsType(int)));
242 connect(PreviewChkB, SIGNAL(toggled(bool)), this, SLOT(updatePreview()));
245 //=======================================================================
246 //function : destructor
248 //=======================================================================
249 VisuGUI_Plot3DPane::~VisuGUI_Plot3DPane()
253 //=======================================================================
254 //function : storePrsParams
255 //purpose : create a copy of Prs parameters and then store current
256 // control values into the Prs
257 //=======================================================================
258 void VisuGUI_Plot3DPane::storePrsParams()
261 myPipeCopy = VISU_Plot3DPL::New();
263 myPipeCopy->SetIDMapper(myPrs->GetPL()->GetIDMapper());
264 myPipeCopy->ShallowCopy(myPrs->GetPL());
265 storeToPrsObject(myPrs);
269 //=======================================================================
270 //function : restorePrsParams
271 //purpose : restore Prs parameters from the copy
272 //=======================================================================
273 void VisuGUI_Plot3DPane::restorePrsParams()
276 myPipeCopy = VISU_Plot3DPL::New();
278 myPrs->GetPL()->ShallowCopy(myPipeCopy);
281 //=======================================================================
282 //function : onPositionSpn
283 //purpose : update absolute position range
284 //=======================================================================
285 void VisuGUI_Plot3DPane::onPositionSpn()
287 if (myPrs && !RelativeChkB->isChecked()) {
288 vtkFloatingPointType minPos, maxPos;
290 myPrs->GetPlot3DPL()->GetMinMaxPosition(minPos, maxPos);
292 if (minPos > PositionSpn->value())
293 minPos = PositionSpn->value();
294 if (maxPos < PositionSpn->value())
295 maxPos = PositionSpn->value();
296 PositionSpn->setRange(minPos, maxPos);
301 //=======================================================================
302 //function : orientationChanged
303 //purpose : update rotation labels and preview
304 //=======================================================================
305 void VisuGUI_Plot3DPane::orientationChanged(int Id)
307 if (Id == 0) { // RBxy->isChecked()
308 LabelRot1->setText(tr("ROTATION_X"));
309 LabelRot2->setText(tr("ROTATION_Y"));
310 } else if (Id == 1) { // RByz->isChecked()
311 LabelRot1->setText(tr("ROTATION_Y"));
312 LabelRot2->setText(tr("ROTATION_Z"));
314 LabelRot1->setText(tr("ROTATION_Z"));
315 LabelRot2->setText(tr("ROTATION_X"));
320 //=======================================================================
321 //function : onRelativePos
322 //purpose : update position value and range
323 //=======================================================================
324 void VisuGUI_Plot3DPane::onRelativePos(bool isRelativePos)
326 vtkFloatingPointType minPos = 0., maxPos = 1., pos = PositionSpn->value();
329 myPrs->GetPlot3DPL()->GetMinMaxPosition(minPos, maxPos);
331 if (-1e-7 < (maxPos - minPos) && (maxPos - minPos) < 1e-7) {
334 if (isRelativePos) // absolute -> relative
335 pos = (pos - minPos) / (maxPos - minPos);
336 else // relative -> absolute
337 pos = minPos * (1. - pos) + maxPos * pos;
344 PositionSpn->setMinValue(minPos);
345 PositionSpn->setMaxValue(maxPos);
346 PositionSpn->setLineStep((maxPos - minPos) / 10.);
347 PositionSpn->setValue(pos);
350 //=======================================================================
351 //function : onPrsType
353 //=======================================================================
354 void VisuGUI_Plot3DPane::onPrsType(int id)
356 NbContoursSpn->setEnabled(id == CONTOUR_PRS_ID);
359 //=======================================================================
360 //function : updatePreview
362 //=======================================================================
363 void VisuGUI_Plot3DPane::updatePreview()
365 if (myInitFromPrs || !myPrs || !myViewWindow)
368 if (PreviewChkB->isChecked()) // place preview plane
370 // get plane preview actor
371 TPlane* planePreview = (TPlane*) myPreviewActor;
373 myPreviewActor = planePreview = new TPlane(myPrs->GetInput()->GetLength());
374 myViewWindow->AddActor(planePreview);
375 fitall = !VISU::GetActor(myPrs, myViewWindow);
377 // set plane parameters corresponding to control values
379 vtkFloatingPointType normal[3], origin[3];
380 myPrs->GetPlot3DPL()->GetBasePlane(origin, normal, true);
381 planePreview->Set(origin, normal);
385 myPreviewActor->SetVisibility(PreviewChkB->isChecked());
387 renderViewFrame(myViewWindow);
390 myPreviewActor->SetInfinitive(false);
391 myViewWindow->onFitAll();
392 myPreviewActor->SetInfinitive(true);
396 //=======================================================================
397 //function : initFromPrsObject
399 //=======================================================================
400 void VisuGUI_Plot3DPane::initFromPrsObject(VISU::Plot3D_i* thePrs)
402 myInitFromPrs = true;
407 switch (thePrs->GetOrientationType()) {
408 case VISU::Plot3D::XY: id = 0; break;
409 case VISU::Plot3D::YZ: id = 1; break;
412 GBOrientation->setButton(id);
413 orientationChanged(id);
416 Rot1->setValue(thePrs->GetRotateX() * 180./PI);
417 Rot2->setValue(thePrs->GetRotateY() * 180./PI);
420 RelativeChkB->setChecked(thePrs->IsPositionRelative());
421 onRelativePos(thePrs->IsPositionRelative()); // update range
422 PositionSpn->setValue(thePrs->GetPlanePosition());
425 ScaleSpn->setValue(thePrs->GetScaleFactor());
428 id = thePrs->GetIsContourPrs() ? CONTOUR_PRS_ID : SURFACE_PRS_ID;
429 GBPrsType->setButton(id);
433 NbContoursSpn->setValue(thePrs->GetNbOfContours());
435 // disable cutting plane controls if the mesh is planar
437 if (thePrs->GetPL()->IsPlanarInput())
439 GBOrientation->setEnabled(false);
440 Rot1 ->setEnabled(false);
441 Rot2 ->setEnabled(false);
442 PositionSpn ->setEnabled(false);
443 RelativeChkB ->setEnabled(false);
444 PreviewChkB ->setEnabled(false);
447 myInitFromPrs = false;
451 //=======================================================================
452 //function : storeToPrsObject
454 //=======================================================================
455 int VisuGUI_Plot3DPane::storeToPrsObject(VISU::Plot3D_i* thePrs)
460 int id = GBOrientation->id (GBOrientation->selected());
461 VISU::Plot3D::Orientation ori;
463 case 0 : ori = VISU::Plot3D::XY; break;
464 case 1 : ori = VISU::Plot3D::YZ; break;
465 default: ori = VISU::Plot3D::ZX;
468 thePrs->SetOrientation(ori, Rot1->value()*PI/180., Rot2->value()*PI/180.);
471 thePrs->SetPlanePosition(PositionSpn->value(), RelativeChkB->isChecked());
474 thePrs->SetScaleFactor(ScaleSpn->value());
477 id = GBPrsType->id (GBPrsType->selected());
478 thePrs->SetContourPrs(id == CONTOUR_PRS_ID);
481 thePrs->SetNbOfContours(NbContoursSpn->value());
486 //=======================================================================
489 //=======================================================================
490 bool VisuGUI_Plot3DPane::check()
492 if (myPreviewActor && myViewWindow) // erase preview
494 myPreviewActor->SetVisibility(false);
495 myViewWindow->RemoveActor(myPreviewActor);
496 myPreviewActor->Delete();
503 void VisuGUI_Plot3DPane::setPlane(int theOrientation, double theXRotation, double theYRotation, double thePlanePos)
507 switch (theOrientation) {
508 case VISU::Plot3D::XY: id = 0; break;
509 case VISU::Plot3D::YZ: id = 1; break;
512 GBOrientation->setButton(id);
513 orientationChanged(id);
514 GBOrientation->setEnabled(false);
518 Rot1->setValue(theXRotation * 180./PI);
519 Rot1->setEnabled(false);
520 Rot2->setValue(theYRotation * 180./PI);
521 Rot2->setEnabled(false);
524 RelativeChkB->setChecked(false);
525 onRelativePos(false); // update range
526 PositionSpn->setValue(thePlanePos);
527 RelativeChkB->setEnabled(false);
528 PositionSpn->setEnabled(false);
532 //=======================================================================
533 //function : Constructor
535 //=======================================================================
536 VisuGUI_Plot3DDlg::VisuGUI_Plot3DDlg (SalomeApp_Module* theModule)
537 : QDialog(VISU::GetDesktop(theModule), "VisuGUI_Plot3DDlg", false, WStyle_Customize |
538 WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu)
540 setCaption(tr("TITLE"));
541 setSizeGripEnabled(TRUE);
543 QVBoxLayout* TopLayout = new QVBoxLayout(this);
544 TopLayout->setSpacing(6);
545 TopLayout->setMargin(11);
547 QTabWidget* aTabBox = new QTabWidget (this);
548 myIsoPane = new VisuGUI_Plot3DPane (this);
549 myIsoPane->setMargin(5);
550 aTabBox->addTab(myIsoPane, tr("PLOT3D_TAB_TITLE"));
551 myScalarPane = new VisuGUI_ScalarBarPane (this, false);
552 myScalarPane->setMargin(5);
553 aTabBox->addTab(myScalarPane, tr("SCALAR_BAR_TAB_TITLE"));
555 TopLayout->addWidget(aTabBox);
557 QGroupBox* GroupButtons = new QGroupBox (this, "GroupButtons");
558 GroupButtons->setGeometry(QRect(10, 10, 281, 48));
559 GroupButtons->setColumnLayout(0, Qt::Vertical);
560 GroupButtons->layout()->setSpacing(0);
561 GroupButtons->layout()->setMargin(0);
562 QGridLayout* GroupButtonsLayout = new QGridLayout (GroupButtons->layout());
563 GroupButtonsLayout->setAlignment(Qt::AlignTop);
564 GroupButtonsLayout->setSpacing(6);
565 GroupButtonsLayout->setMargin(11);
567 QPushButton* buttonOk = new QPushButton (tr("&OK"), GroupButtons, "buttonOk");
568 buttonOk->setAutoDefault(TRUE);
569 buttonOk->setDefault(TRUE);
570 GroupButtonsLayout->addWidget(buttonOk, 0, 0);
571 GroupButtonsLayout->addItem(new QSpacerItem (5, 5, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 1);
572 QPushButton* buttonCancel = new QPushButton (tr("&Cancel") , GroupButtons, "buttonCancel");
573 buttonCancel->setAutoDefault(TRUE);
574 GroupButtonsLayout->addWidget(buttonCancel, 0, 2);
575 QPushButton* buttonHelp = new QPushButton (tr("&Help") , GroupButtons, "buttonHelp");
576 buttonHelp->setAutoDefault(TRUE);
577 GroupButtonsLayout->addWidget(buttonHelp, 0, 3);
579 TopLayout->addWidget(GroupButtons);
581 // signals and slots connections
582 connect(buttonOk, SIGNAL(clicked()), this, SLOT(accept()));
583 connect(buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
584 connect(buttonHelp, SIGNAL(clicked()), this, SLOT(onHelp()));
587 //=======================================================================
590 //=======================================================================
591 void VisuGUI_Plot3DDlg::accept()
593 if (myIsoPane->check() && myScalarPane->check())
595 myScalarPane->deletePreview();
600 //=======================================================================
603 //=======================================================================
604 void VisuGUI_Plot3DDlg::reject()
606 myIsoPane->check(); // hide preview
607 myScalarPane->deletePreview();
612 //=======================================================================
615 //=======================================================================
616 void VisuGUI_Plot3DDlg::onHelp()
618 QString aHelpFileName = "plot_3d_presentation.htm";
619 LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
621 VisuGUI* aVisuGUI = dynamic_cast<VisuGUI*>( app->activeModule() );
622 app->onHelpContextModule(aVisuGUI ? app->moduleName(aVisuGUI->moduleName()) : QString(""), aHelpFileName);
625 SUIT_MessageBox::warn1(0, QObject::tr("WRN_WARNING"),
626 QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
627 arg(app->resourceMgr()->stringValue("ExternalBrowser", "application")).arg(aHelpFileName),
628 QObject::tr("BUT_OK"));
632 //=======================================================================
633 //function : setPlane
635 //=======================================================================
636 void VisuGUI_Plot3DDlg::setPlane(int theOrientation, double theXRotation, double theYRotation, double thePlanePos)
638 myIsoPane->setPlane(theOrientation, theXRotation, theYRotation, thePlanePos);