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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : VisuGUI_Plot3DDlg.cxx
25 // Author : Laurent CORNABE & Hubert ROLLAND
29 #include "VisuGUI_Plot3DDlg.h"
32 #include "VisuGUI_Tools.h"
34 #include "VISU_ViewManager_i.hh"
35 #include "VISU_Plot3DPL.hxx"
37 #include "SALOME_Actor.h"
38 #include "SVTK_ViewWindow.h"
39 #include "SUIT_Desktop.h"
42 #include <qvalidator.h>
43 #include <qtabwidget.h>
45 #include <vtkUnstructuredGrid.h>
46 #include <vtkDataSetMapper.h>
47 #include <vtkRenderer.h>
48 #include <vtkPlaneSource.h>
49 #include <vtkPolyData.h>
54 #define SURFACE_PRS_ID 0
55 #define CONTOUR_PRS_ID 1
57 //=======================================================================
58 //function : renderViewFrame
60 //=======================================================================
61 static void renderViewFrame (SVTK_ViewWindow* vw)
64 vw->getRenderer()->ResetCameraClippingRange();
69 //=======================================================================
71 //purpose : actor of plane preview
72 //=======================================================================
73 class TPlane : public SALOME_Actor
76 vtkDataSetMapper* myMapper;
77 vtkPlaneSource* myPlaneSource;
81 TPlane(float planeSize): mySize(planeSize)
85 // set plane parameters
86 void Set(float origin[3], float normal[3])
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 ];
94 myPlaneSource->SetOrigin(origin);
95 myPlaneSource->SetPoint1(point1);
96 myPlaneSource->SetPoint2(point2);
97 myPlaneSource->SetCenter(origin);
99 vtkTypeMacro(TPlane,SALOME_Actor);
103 myPlaneSource = vtkPlaneSource::New();
104 myMapper = vtkDataSetMapper::New();
105 myMapper->SetInput(myPlaneSource->GetOutput());
114 myMapper->RemoveAllInputs();
116 myPlaneSource->UnRegisterAllOutputs();
117 myPlaneSource->Delete();
120 TPlane(const TPlane&);
121 void operator=(const TPlane&);
124 //=======================================================================
125 //function : VisuGUI_Plot3DPane
127 //=======================================================================
128 VisuGUI_Plot3DPane::VisuGUI_Plot3DPane (QWidget* parent)
129 : QVBox(parent), myInitFromPrs(false), myPreviewActor(NULL),
130 myViewWindow(VISU::GetViewWindow()), myPrs(NULL), myPipeCopy(NULL)
132 layout()->setAlignment(Qt::AlignTop);
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);
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);
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);
166 LabelRot1 = new QLabel (tr("ROTATION_X"), GBrot, "LabelRot1");
167 GBrotLayout->addWidget(LabelRot1, 0, 0);
169 Rot1 = new QtxDblSpinBox (-180, 180, 5, GBrot);
170 Rot1->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
171 GBrotLayout->addWidget(Rot1, 0, 1);
173 LabelRot2 = new QLabel (tr("ROTATION_Y"), GBrot, "LabelRot2");
174 GBrotLayout->addWidget(LabelRot2, 1, 0);
176 Rot2 = new QtxDblSpinBox (-180, 180, 5, GBrot);
177 Rot2->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
178 GBrotLayout->addWidget(Rot2, 1, 1);
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);
191 QLabel * valueLabel = new QLabel (tr("POSITION_VALUE"), GBpos, "LabelRot1");
192 GBposLayout->addWidget(valueLabel, 0, 0);
194 PositionSpn = new QtxDblSpinBox (0, 1, 0.1, GBpos);
195 GBposLayout->addWidget(PositionSpn, 0, 1);
197 RelativeChkB = new QCheckBox (tr("RELATIVE"), GBpos, "RelativeChkB");
198 RelativeChkB->setChecked(true);
199 GBposLayout->addWidget(RelativeChkB, 0, 2);
201 // Scale, Presentation type, Nb Contours, Preview
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);
209 QLabel* scaleLabel = new QLabel (tr("SCALE"), bottomFrame);
210 ScaleSpn = new QtxDblSpinBox (-1.e6, 1.e6, 0.1, bottomFrame);
212 GBPrsType = new QHButtonGroup (tr("PRESENTATION_TYPE"), bottomFrame);
213 new QRadioButton (tr("SURFACE"), GBPrsType);
214 new QRadioButton (tr("CONTOUR"), GBPrsType);
216 QLabel* nbContLabel = new QLabel (tr("NUMBER_CONTOURS"), bottomFrame);
217 NbContoursSpn = new QSpinBox (1, 999, 1, bottomFrame, "NbContoursSpn");
219 PreviewChkB = new QCheckBox (tr("PREVIEW"), bottomFrame);
220 PreviewChkB->setChecked(false);
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);
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()));
239 //=======================================================================
240 //function : destructor
242 //=======================================================================
243 VisuGUI_Plot3DPane::~VisuGUI_Plot3DPane()
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()
255 myPipeCopy = VISU_Plot3DPL::New();
257 myPipeCopy->ShallowCopy(myPrs->GetPL());
258 storeToPrsObject(myPrs);
262 //=======================================================================
263 //function : restorePrsParams
264 //purpose : restore Prs parameters from the copy
265 //=======================================================================
266 void VisuGUI_Plot3DPane::restorePrsParams()
269 myPipeCopy = VISU_Plot3DPL::New();
271 myPrs->GetPL()->ShallowCopy(myPipeCopy);
274 //=======================================================================
275 //function : onPositionSpn
276 //purpose : update absolute position range
277 //=======================================================================
278 void VisuGUI_Plot3DPane::onPositionSpn()
280 if (myPrs && !RelativeChkB->isChecked()) {
281 float minPos, maxPos;
283 myPrs->GetPlot3DPL()->GetMinMaxPosition(minPos, maxPos);
285 if (minPos > PositionSpn->value())
286 minPos = PositionSpn->value();
287 if (maxPos < PositionSpn->value())
288 maxPos = PositionSpn->value();
289 PositionSpn->setRange(minPos, maxPos);
294 //=======================================================================
295 //function : orientationChanged
296 //purpose : update rotation labels and preview
297 //=======================================================================
298 void VisuGUI_Plot3DPane::orientationChanged(int Id)
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"));
307 LabelRot1->setText(tr("ROTATION_Z"));
308 LabelRot2->setText(tr("ROTATION_X"));
313 //=======================================================================
314 //function : onRelativePos
315 //purpose : update position value and range
316 //=======================================================================
317 void VisuGUI_Plot3DPane::onRelativePos(bool isRelativePos)
319 float minPos = 0., maxPos = 1., pos = PositionSpn->value();
322 myPrs->GetPlot3DPL()->GetMinMaxPosition(minPos, maxPos);
324 if (-1e-7 < (maxPos - minPos) && (maxPos - minPos) < 1e-7) {
327 if (isRelativePos) // absolute -> relative
328 pos = (pos - minPos) / (maxPos - minPos);
329 else // relative -> absolute
330 pos = minPos * (1. - pos) + maxPos * pos;
337 PositionSpn->setMinValue(minPos);
338 PositionSpn->setMaxValue(maxPos);
339 PositionSpn->setLineStep((maxPos - minPos) / 10.);
340 PositionSpn->setValue(pos);
343 //=======================================================================
344 //function : onPrsType
346 //=======================================================================
347 void VisuGUI_Plot3DPane::onPrsType(int id)
349 NbContoursSpn->setEnabled(id == CONTOUR_PRS_ID);
352 //=======================================================================
353 //function : updatePreview
355 //=======================================================================
356 void VisuGUI_Plot3DPane::updatePreview()
358 if (myInitFromPrs || !myPrs || !myViewWindow)
361 if (PreviewChkB->isChecked()) // place preview plane
363 // get plane preview actor
364 TPlane* planePreview = (TPlane*) myPreviewActor;
366 myPreviewActor = planePreview = new TPlane(myPrs->GetInput()->GetLength());
367 myViewWindow->AddActor(planePreview);
368 fitall = !VISU::GetActor(myPrs, myViewWindow);
370 // set plane parameters corresponding to control values
372 float normal[3], origin[3];
373 myPrs->GetPlot3DPL()->GetBasePlane(origin, normal, true);
374 planePreview->Set(origin, normal);
378 myPreviewActor->SetVisibility(PreviewChkB->isChecked());
380 renderViewFrame(myViewWindow);
383 myPreviewActor->SetInfinitive(false);
384 myViewWindow->onFitAll();
385 myPreviewActor->SetInfinitive(true);
389 //=======================================================================
390 //function : initFromPrsObject
392 //=======================================================================
393 void VisuGUI_Plot3DPane::initFromPrsObject(VISU::Plot3D_i* thePrs)
395 myInitFromPrs = true;
400 switch (thePrs->GetOrientationType()) {
401 case VISU::Plot3D::XY: id = 0; break;
402 case VISU::Plot3D::YZ: id = 1; break;
405 GBOrientation->setButton(id);
406 orientationChanged(id);
409 Rot1->setValue(thePrs->GetRotateX() * 180./PI);
410 Rot2->setValue(thePrs->GetRotateY() * 180./PI);
413 RelativeChkB->setChecked(thePrs->IsPositionRelative());
414 onRelativePos(thePrs->IsPositionRelative()); // update range
415 PositionSpn->setValue(thePrs->GetPlanePosition());
418 ScaleSpn->setValue(thePrs->GetScaleFactor());
421 id = thePrs->GetIsContourPrs() ? CONTOUR_PRS_ID : SURFACE_PRS_ID;
422 GBPrsType->setButton(id);
426 NbContoursSpn->setValue(thePrs->GetNbOfContours());
428 // disable cutting plane controls if the mesh is planar
430 if (thePrs->GetPL()->IsPlanarInput())
432 GBOrientation->setEnabled(false);
433 Rot1 ->setEnabled(false);
434 Rot2 ->setEnabled(false);
435 PositionSpn ->setEnabled(false);
436 RelativeChkB ->setEnabled(false);
437 PreviewChkB ->setEnabled(false);
440 myInitFromPrs = false;
444 //=======================================================================
445 //function : storeToPrsObject
447 //=======================================================================
448 int VisuGUI_Plot3DPane::storeToPrsObject(VISU::Plot3D_i* thePrs)
453 int id = GBOrientation->id (GBOrientation->selected());
454 VISU::Plot3D::Orientation ori;
456 case 0 : ori = VISU::Plot3D::XY; break;
457 case 1 : ori = VISU::Plot3D::YZ; break;
458 default: ori = VISU::Plot3D::ZX;
461 thePrs->SetOrientation(ori, Rot1->value()*PI/180., Rot2->value()*PI/180.);
464 thePrs->SetPlanePosition(PositionSpn->value(), RelativeChkB->isChecked());
467 thePrs->SetScaleFactor(ScaleSpn->value());
470 id = GBPrsType->id (GBPrsType->selected());
471 thePrs->SetContourPrs(id == CONTOUR_PRS_ID);
474 thePrs->SetNbOfContours(NbContoursSpn->value());
479 //=======================================================================
482 //=======================================================================
483 bool VisuGUI_Plot3DPane::check()
485 if (myPreviewActor && myViewWindow) // erase preview
487 myPreviewActor->SetVisibility(false);
488 myViewWindow->RemoveActor(myPreviewActor);
489 myPreviewActor->Delete();
496 //=======================================================================
497 //function : Constructor
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)
504 setCaption(tr("TITLE"));
505 setSizeGripEnabled(TRUE);
507 QVBoxLayout* TopLayout = new QVBoxLayout(this);
508 TopLayout->setSpacing(6);
509 TopLayout->setMargin(11);
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"));
519 TopLayout->addWidget(aTabBox);
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);
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);
540 TopLayout->addWidget(GroupButtons);
542 // signals and slots connections
543 connect(buttonOk, SIGNAL(clicked()), this, SLOT(accept()));
544 connect(buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
547 //=======================================================================
550 //=======================================================================
551 void VisuGUI_Plot3DDlg::accept()
553 /*if (!VISU::CheckActiveStudyLock()) {
556 if (myIsoPane->check() && myScalarPane->check()) {
558 VISU::Plot3D_i* prs = myIsoPane->GetPrs();
559 bool isCreation = !VISU::GetActor(prs, myViewWindow);
560 if (storeToPrsObject(prs)) {
561 if (isCreation) { // creation
564 VISU::CreateActor(prs);
570 myViewWindow->onFitAll();
573 VISU::RecreateActor(prs);
574 renderViewFrame(myViewWindow);
578 prs->RemoveFromStudy();
579 //study->updateObjBrowser();
587 //=======================================================================
590 //=======================================================================
591 void VisuGUI_Plot3DDlg::reject()
593 myIsoPane->check(); // hide preview
595 /*if (!isModal() && myIsoPane->GetPrs() &&
596 !VISU::GetActor(myIsoPane->GetPrs(), myViewWindow)) {
597 _PTR(Study) aStudy = VISU::GetCStudy(VISU::GetAppStudy(myModule));
598 if (!aStudy->GetProperties()->IsLocked()) {
599 myIsoPane->GetPrs()->RemoveFromStudy();
600 myIsoPane->GetStudyFrame()->getStudy()->updateObjBrowser();