1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 #include "VisuGUI_ClippingDlg.h"
24 #include "VisuGUI_Tools.h"
25 #include "VisuGUI_ViewTools.h"
27 #include "VISU_Prs3d_i.hh"
28 #include "VISU_Result_i.hh"
30 #include "VISU_PipeLine.hxx"
32 #include "LightApp_SelectionMgr.h"
33 #include "LightApp_Application.h"
35 #include "SVTK_ViewWindow.h"
37 #include "SUIT_Session.h"
38 #include "SUIT_Desktop.h"
39 #include "SUIT_MessageBox.h"
40 #include "SUIT_ResourceMgr.h"
41 #include "SUIT_OverrideCursor.h"
43 #include "SALOME_Actor.h"
47 #include <qpushbutton.h>
48 #include <qcombobox.h>
49 #include <qcheckbox.h>
51 #include <qgroupbox.h>
52 #include <qvalidator.h>
53 #include <qtabwidget.h>
54 #include <qhbuttongroup.h>
55 #include <qradiobutton.h>
60 #include <vtkCamera.h>
61 #include <vtkRenderer.h>
62 #include <vtkDataSet.h>
63 #include <vtkDataSetMapper.h>
64 #include <vtkImplicitFunction.h>
65 #include <vtkPlaneSource.h>
66 #include <vtkPolyData.h>
67 #include <vtkUnstructuredGrid.h>
68 #include <vtkProperty.h>
76 float GetFloat (const QString& theValue, float theDefault)
78 if (theValue.isEmpty()) return theDefault;
79 SUIT_ResourceMgr* aResourceMgr = VISU::GetResourceMgr();
80 QString aValue = aResourceMgr->stringValue("VISU",theValue);
81 if (aValue.isEmpty()) return theDefault;
82 return aValue.toFloat();
85 void RenderViewWindow (SVTK_ViewWindow* vw)
88 vw->getRenderer()->ResetCameraClippingRange();
93 void RangeStepAndValidator (QtxDblSpinBox* theSpinBox, double min, double max,
94 double step, unsigned short decimals)
96 theSpinBox->setRange(min, max);
97 theSpinBox->setLineStep(step);
98 ((QDoubleValidator*)theSpinBox->validator())->setRange(min, max, decimals);
102 //=================================================================================
103 //class : OrientedPlane
105 //=================================================================================
106 OrientedPlane* OrientedPlane::New()
108 return new OrientedPlane();
111 OrientedPlane* OrientedPlane::New (SVTK_ViewWindow* vw)
113 return new OrientedPlane(vw);
116 void OrientedPlane::SetOrientation(VISU::Orientation theOrientation)
118 myOrientation = theOrientation;
121 VISU::Orientation OrientedPlane::GetOrientation()
123 return myOrientation;
126 void OrientedPlane::SetDistance(float theDistance)
128 myDistance = theDistance;
131 float OrientedPlane::GetDistance()
136 void OrientedPlane::ShallowCopy(OrientedPlane* theOrientedPlane)
138 SetNormal(theOrientedPlane->GetNormal());
139 SetOrigin(theOrientedPlane->GetOrigin());
141 myOrientation = theOrientedPlane->GetOrientation();
142 myDistance = theOrientedPlane->GetDistance();
144 myAngle[0] = theOrientedPlane->myAngle[0];
145 myAngle[1] = theOrientedPlane->myAngle[1];
147 myPlaneSource->SetNormal(theOrientedPlane->myPlaneSource->GetNormal());
148 myPlaneSource->SetOrigin(theOrientedPlane->myPlaneSource->GetOrigin());
149 myPlaneSource->SetPoint1(theOrientedPlane->myPlaneSource->GetPoint1());
150 myPlaneSource->SetPoint2(theOrientedPlane->myPlaneSource->GetPoint2());
153 OrientedPlane::OrientedPlane(SVTK_ViewWindow* vw):
154 myOrientation(VISU::XY),
159 myViewWindow->AddActor(myActor);
162 OrientedPlane::OrientedPlane():
163 myOrientation(VISU::XY),
170 void OrientedPlane::Init()
172 myPlaneSource = vtkPlaneSource::New();
174 myAngle[0] = myAngle[1] = 0.0;
176 // Create and display actor
177 myMapper = vtkDataSetMapper::New();
178 myMapper->SetInput(myPlaneSource->GetOutput());
180 myActor = SALOME_Actor::New();
181 myActor->VisibilityOff();
182 myActor->PickableOff();
183 myActor->SetInfinitive(true);
184 myActor->SetMapper(myMapper);
186 vtkProperty* aProp = vtkProperty::New();
189 SUIT_ResourceMgr* aResourceMgr = VISU::GetResourceMgr();
191 QColor aFillColor = aResourceMgr->colorValue("SMESH", "fill_color", QColor(0, 170, 255));
192 anRGB[0] = aFillColor.red()/255.;
193 anRGB[1] = aFillColor.green()/255.;
194 anRGB[2] = aFillColor.blue()/255.;
195 aProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
196 aProp->SetOpacity(0.75);
197 myActor->SetProperty(aProp);
200 vtkProperty* aBackProp = vtkProperty::New();
201 QColor aBackFaceColor = aResourceMgr->colorValue("SMESH", "backface_color", QColor(0, 0, 255));//@
202 anRGB[0] = aBackFaceColor.red()/255.;
203 anRGB[1] = aBackFaceColor.green()/255.;
204 anRGB[2] = aBackFaceColor.blue()/255.;
205 aBackProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
206 aBackProp->SetOpacity(0.75);
207 myActor->SetBackfaceProperty(aBackProp);
211 OrientedPlane::~OrientedPlane()
213 if ( !myViewWindow.isNull() )
214 myViewWindow->RemoveActor(myActor);
218 myMapper->RemoveAllInputs();
221 // commented: porting to vtk 5.0
222 //myPlaneSource->UnRegisterAllOutputs();
223 myPlaneSource->Delete();
226 struct TSetVisiblity {
227 TSetVisiblity(int theIsVisible): myIsVisible(theIsVisible){}
228 void operator()(VISU::TVTKPlane& theOrientedPlane){
229 theOrientedPlane->myActor->SetVisibility(myIsVisible);
234 //=================================================================================
235 // class : VisuGUI_ClippingDlg()
238 //=================================================================================
239 VisuGUI_ClippingDlg::VisuGUI_ClippingDlg (VisuGUI* theModule,
243 : QDialog(VISU::GetDesktop(theModule), name, modal, WStyle_Customize |
244 WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
245 mySelectionMgr(VISU::GetSelectionMgr(theModule)),
246 myVisuGUI(theModule),
248 myIsSelectPlane(false)
251 setName("VisuGUI_ClippingDlg");
252 setCaption(tr("TITLE"));
253 setSizeGripEnabled(TRUE);
254 QGridLayout* VisuGUI_ClippingDlgLayout = new QGridLayout(this);
255 VisuGUI_ClippingDlgLayout->setSpacing(6);
256 VisuGUI_ClippingDlgLayout->setMargin(11);
258 // Controls for selecting, creating, deleting planes
259 QGroupBox* GroupPlanes = new QGroupBox (this, "GroupPlanes");
260 GroupPlanes->setTitle(tr("GRP_PLANES"));
261 GroupPlanes->setColumnLayout(0, Qt::Vertical);
262 GroupPlanes->layout()->setSpacing(0);
263 GroupPlanes->layout()->setMargin(0);
264 QGridLayout* GroupPlanesLayout = new QGridLayout (GroupPlanes->layout());
265 GroupPlanesLayout->setAlignment(Qt::AlignTop);
266 GroupPlanesLayout->setSpacing(6);
267 GroupPlanesLayout->setMargin(11);
269 ComboBoxPlanes = new QComboBox (GroupPlanes, "ComboBoxPlanes");
270 GroupPlanesLayout->addWidget(ComboBoxPlanes, 0, 0);
272 QSpacerItem* spacerGP = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
273 GroupPlanesLayout->addItem(spacerGP, 0, 1);
275 buttonNew = new QPushButton (GroupPlanes, "buttonNew");
276 buttonNew->setText(tr("BUT_NEW"));
277 GroupPlanesLayout->addWidget(buttonNew, 0, 2);
279 buttonDelete = new QPushButton(GroupPlanes, "buttonDelete");
280 buttonDelete->setText(tr("BUT_DELETE"));
281 GroupPlanesLayout->addWidget(buttonDelete, 0, 3);
283 // Controls for defining plane parameters
286 QGroupBox* GroupParameters = new QGroupBox(this, "GroupParameters");
287 GroupParameters->setTitle(tr("GRP_PARAMETERS"));
288 GroupParameters->setColumnLayout(0, Qt::Vertical);
289 GroupParameters->layout()->setSpacing(0);
290 GroupParameters->layout()->setMargin(0);
291 QGridLayout* GroupParametersLayout = new QGridLayout (GroupParameters->layout());
292 GroupParametersLayout->setAlignment(Qt::AlignTop);
293 GroupParametersLayout->setSpacing(6);
294 GroupParametersLayout->setMargin(11);
296 TabPane = new QTabWidget (GroupParameters);
297 TabPane->addTab(createParamsTab() , tr("TAB_NON_STRUCTURED"));
298 TabPane->addTab(createIJKParamsTab(), tr("TAB_IJK_STRUCTURED"));
299 GroupParametersLayout->addWidget(TabPane, 0, 0);
301 // "Show preview" and "Auto Apply" check boxes
303 PreviewCheckBox = new QCheckBox (tr("SHOW_PREVIEW_CHK"), this);
304 PreviewCheckBox->setChecked(true);
306 AutoApplyCheckBox = new QCheckBox (tr("AUTO_APPLY_CHK"), this);
307 AutoApplyCheckBox->setChecked(false);
309 // Controls for "Ok", "Apply" and "Close" button
310 QGroupBox* GroupButtons = new QGroupBox (this, "GroupButtons");
311 GroupButtons->setSizePolicy(QSizePolicy((QSizePolicy::SizeType)7,
312 (QSizePolicy::SizeType)0, 0, 0,
313 GroupButtons->sizePolicy().hasHeightForWidth()));
314 GroupButtons->setGeometry(QRect(10, 10, 281, 48));
315 //GroupButtons->setTitle(tr(""));
316 GroupButtons->setColumnLayout(0, Qt::Vertical);
317 GroupButtons->layout()->setSpacing(0);
318 GroupButtons->layout()->setMargin(0);
319 QGridLayout* GroupButtonsLayout = new QGridLayout (GroupButtons->layout());
320 GroupButtonsLayout->setAlignment(Qt::AlignTop);
321 GroupButtonsLayout->setSpacing(6);
322 GroupButtonsLayout->setMargin(11);
323 buttonHelp = new QPushButton (GroupButtons, "buttonHelp");
324 buttonHelp->setText(tr("BUT_HELP"));
325 buttonHelp->setAutoDefault(TRUE);
326 GroupButtonsLayout->addWidget(buttonHelp, 0, 4);
327 buttonCancel = new QPushButton (GroupButtons, "buttonCancel");
328 buttonCancel->setText(tr("BUT_CLOSE"));
329 buttonCancel->setAutoDefault(TRUE);
330 GroupButtonsLayout->addWidget(buttonCancel, 0, 3);
331 buttonApply = new QPushButton (GroupButtons, "buttonApply");
332 buttonApply->setText(tr("BUT_APPLY"));
333 buttonApply->setAutoDefault(TRUE);
334 GroupButtonsLayout->addWidget(buttonApply, 0, 1);
335 QSpacerItem* spacer_9 = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
336 GroupButtonsLayout->addItem(spacer_9, 0, 2);
337 buttonOk = new QPushButton (GroupButtons, "buttonOk");
338 buttonOk->setText(tr("BUT_OK"));
339 buttonOk->setAutoDefault(TRUE);
340 buttonOk->setDefault(TRUE);
341 GroupButtonsLayout->addWidget(buttonOk, 0, 0);
343 VisuGUI_ClippingDlgLayout->addMultiCellWidget(GroupPlanes, 0, 0, 0, 1);
344 VisuGUI_ClippingDlgLayout->addMultiCellWidget(GroupParameters, 1, 1, 0, 1);
345 VisuGUI_ClippingDlgLayout->addWidget(PreviewCheckBox, 2, 0);
346 VisuGUI_ClippingDlgLayout->addWidget(AutoApplyCheckBox, 2, 1);
347 VisuGUI_ClippingDlgLayout->addMultiCellWidget(GroupButtons, 3, 3, 0, 1);
350 VISU::RangeStepAndValidator(SpinBoxDistance, 0.0, 1.0, 0.01, 3);
351 VISU::RangeStepAndValidator(SpinBoxRot1, -180.0, 180.0, 1, 3);
352 VISU::RangeStepAndValidator(SpinBoxRot2, -180.0, 180.0, 1, 3);
354 ComboBoxOrientation->insertItem(tr("PARALLEL_XOY_COMBO_ITEM"));
355 ComboBoxOrientation->insertItem(tr("PARALLEL_YOZ_COMBO_ITEM"));
356 ComboBoxOrientation->insertItem(tr("PARALLEL_ZOX_COMBO_ITEM"));
358 SpinBoxDistance->setValue(0.5);
360 onSelectionChanged();
362 // signals and slots connections :
363 connect(ComboBoxPlanes , SIGNAL(activated(int)) , this, SLOT(onSelectPlane(int)));
364 connect(buttonNew , SIGNAL(clicked()) , this, SLOT(ClickOnNew()));
365 connect(buttonDelete , SIGNAL(clicked()) , this, SLOT(ClickOnDelete()));
366 connect(ComboBoxOrientation , SIGNAL(activated(int)) , this, SLOT(onSelectOrientation(int)));
367 connect(SpinBoxDistance , SIGNAL(valueChanged(double)) , this, SLOT(SetCurrentPlaneParam()));
368 connect(SpinBoxRot1 , SIGNAL(valueChanged(double)) , this, SLOT(SetCurrentPlaneParam()));
369 connect(SpinBoxRot2 , SIGNAL(valueChanged(double)) , this, SLOT(SetCurrentPlaneParam()));
370 connect(ButtonGroupIJKAxis , SIGNAL(clicked(int)) , this, SLOT(onIJKAxisChanged(int)));
371 connect(SpinBoxIJKIndex , SIGNAL(valueChanged(int)) , this, SLOT(SetCurrentPlaneIJKParam()));
372 connect(CheckBoxIJKPlaneReverse, SIGNAL(toggled(bool)) , this, SLOT(SetCurrentPlaneIJKParam()));
373 connect(TabPane , SIGNAL(currentChanged (QWidget*)), this, SLOT(onTabChanged(QWidget*)));
375 connect(PreviewCheckBox , SIGNAL(toggled(bool)), this, SLOT(OnPreviewToggle(bool)));
376 connect(AutoApplyCheckBox, SIGNAL(toggled(bool)), this, SLOT(ClickOnApply()));
378 connect(buttonOk , SIGNAL(clicked()), this, SLOT(ClickOnOk()));
379 connect(buttonApply , SIGNAL(clicked()), this, SLOT(ClickOnApply()));
380 connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()));
381 connect(buttonHelp , SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
383 connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionChanged()));
388 //=================================================================================
389 // function : ~VisuGUI_ClippingDlg()
391 //=================================================================================
392 VisuGUI_ClippingDlg::~VisuGUI_ClippingDlg()
394 // no need to delete child widgets, Qt does it all for us
396 std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
397 VISU::RenderViewWindow(VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI));
400 //=================================================================================
401 // function : createParamsTab
403 //=================================================================================
404 QWidget* VisuGUI_ClippingDlg::createParamsTab()
406 QFrame* GroupParameters = new QFrame(this);
407 QGridLayout* GroupParametersLayout = new QGridLayout(GroupParameters);
408 GroupParametersLayout->setAlignment(Qt::AlignTop);
409 GroupParametersLayout->setSpacing(6);
410 GroupParametersLayout->setMargin(11);
412 TextLabelOrientation = new QLabel(GroupParameters, "TextLabelOrientation");
413 TextLabelOrientation->setText(tr("LBL_ORIENTATION"));
414 GroupParametersLayout->addWidget(TextLabelOrientation, 0, 0);
416 ComboBoxOrientation = new QComboBox(GroupParameters, "ComboBoxOrientation");
417 GroupParametersLayout->addWidget(ComboBoxOrientation, 0, 1);
419 TextLabelDistance = new QLabel(GroupParameters, "TextLabelDistance");
420 TextLabelDistance->setText(tr("LBL_DISTANCE"));
421 GroupParametersLayout->addWidget(TextLabelDistance, 1, 0);
423 SpinBoxDistance = new QtxDblSpinBox(GroupParameters, "SpinBoxDistance");
424 GroupParametersLayout->addWidget(SpinBoxDistance, 1, 1);
426 TextLabelRot1 = new QLabel(GroupParameters, "TextLabelRot1");
427 TextLabelRot1->setText(tr("LBL_ROTATION_YZ"));
428 GroupParametersLayout->addWidget(TextLabelRot1, 2, 0);
430 SpinBoxRot1 = new QtxDblSpinBox(GroupParameters, "SpinBoxRot1");
431 GroupParametersLayout->addWidget(SpinBoxRot1, 2, 1);
433 TextLabelRot2 = new QLabel(GroupParameters, "TextLabelRot2");
434 TextLabelRot2->setText(tr("LBL_ROTATION_XZ"));
435 GroupParametersLayout->addWidget(TextLabelRot2, 3, 0);
437 SpinBoxRot2 = new QtxDblSpinBox(GroupParameters, "SpinBoxRot2");
438 GroupParametersLayout->addWidget(SpinBoxRot2, 3, 1);
440 return GroupParameters;
443 //=================================================================================
444 // function : createIJKParamsTab
446 //=================================================================================
447 QWidget* VisuGUI_ClippingDlg::createIJKParamsTab()
450 WidgetIJKTab = new QFrame(this);
451 QGridLayout* IJKParametersLayout = new QGridLayout(WidgetIJKTab);
452 IJKParametersLayout->setAlignment(Qt::AlignTop);
453 IJKParametersLayout->setSpacing(6);
454 IJKParametersLayout->setMargin(11);
457 ButtonGroupIJKAxis = new QHButtonGroup (tr("GRP_IJK_AXIS"), WidgetIJKTab);
458 new QRadioButton (tr("I_RADIO_BTN"), ButtonGroupIJKAxis); // 0
459 new QRadioButton (tr("J_RADIO_BTN"), ButtonGroupIJKAxis); // 1
460 new QRadioButton (tr("K_RADIO_BTN"), ButtonGroupIJKAxis); // 2
461 ButtonGroupIJKAxis->setButton(0);
464 TextLabelIJKIndex = new QLabel(WidgetIJKTab, "TextLabelIJKIndex");
465 TextLabelIJKIndex->setText(tr("LBL_IJK_INDEX"));
466 SpinBoxIJKIndex = new QSpinBox(WidgetIJKTab, "SpinBoxIJKIndex");
469 CheckBoxIJKPlaneReverse = new QCheckBox (tr("REVERSE_NORMAL_CHK"), WidgetIJKTab);
470 CheckBoxIJKPlaneReverse->setChecked(false);
472 IJKParametersLayout->addMultiCellWidget(ButtonGroupIJKAxis, 0, 0, 0, 1);
473 IJKParametersLayout->addWidget(TextLabelIJKIndex, 1, 0);
474 IJKParametersLayout->addWidget(SpinBoxIJKIndex, 1, 1);
475 IJKParametersLayout->addWidget(CheckBoxIJKPlaneReverse, 2, 0);
480 //=================================================================================
481 // function : ClickOnApply()
483 //=================================================================================
484 void VisuGUI_ClippingDlg::ClickOnApply()
489 if (SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI)) {
490 SUIT_OverrideCursor wc;
492 QWidget *aCurrWid = this->focusWidget();
493 aCurrWid->clearFocus();
494 aCurrWid->setFocus();
496 // Save clipping planes, currently applied to the presentation
497 // to enable restoring this state in case of failure.
498 // Refer to bugs IPAL8849, IPAL8850 for more information.
499 typedef vtkSmartPointer<vtkPlane> TPln;
500 typedef std::vector<TPln> TPlns;
501 bool isFailed = false;
503 int iopl = 0, nbOldPlanes = myPrs3d->GetNumberOfClippingPlanes();
504 for (; iopl < nbOldPlanes; iopl++) {
505 anOldPlanes.push_back(myPrs3d->GetClippingPlane(iopl));
508 // Try to apply new clipping
509 myPrs3d->RemoveAllClippingPlanes();
511 VISU::TPlanes::iterator anIter = myPlanes.begin();
512 for (; anIter != myPlanes.end(); anIter++) {
513 OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow);
514 anOrientedPlane->ShallowCopy(anIter->GetPointer());
515 if (!myPrs3d->AddClippingPlane(anOrientedPlane)) {
518 anOrientedPlane->Delete();
521 // Check contents of the resulting (clipped) presentation data
523 VISU_PipeLine* aPL = myPrs3d->GetPipeLine();
524 vtkMapper* aMapper = aPL->GetMapper();
525 vtkDataSet* aPrsData = aMapper->GetInput();
527 if (aPrsData->GetNumberOfCells() < 1) {
533 // Restore previous clipping state because of failure.
534 myPrs3d->RemoveAllClippingPlanes();
536 TPlns::iterator anOldIter = anOldPlanes.begin();
537 for (; anOldIter != anOldPlanes.end(); anOldIter++) {
538 myPrs3d->AddClippingPlane(anOldIter->GetPointer());
541 SUIT_MessageBox::warn1(VISU::GetDesktop(myVisuGUI),
543 tr("WRN_EMPTY_RESULTING_PRS"),
547 //VISU::RenderViewWindow(aViewWindow);
548 VISU::RepaintViewWindows(myVisuGUI, myIO);
552 //=================================================================================
553 // function : ClickOnOk()
555 //=================================================================================
556 void VisuGUI_ClippingDlg::ClickOnOk()
562 //=================================================================================
563 // function : ClickOnCancel()
565 //=================================================================================
566 void VisuGUI_ClippingDlg::ClickOnCancel()
571 //=================================================================================
572 // function : ClickOnHelp()
574 //=================================================================================
575 void VisuGUI_ClippingDlg::ClickOnHelp()
577 QString aHelpFileName = "clipping_page.html";
578 LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
580 app->onHelpContextModule(myVisuGUI ? app->moduleName(myVisuGUI->moduleName()) : QString(""), aHelpFileName);
584 platform = "winapplication";
586 platform = "application";
588 SUIT_MessageBox::warn1(0, QObject::tr("WRN_WARNING"),
589 QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
590 arg(app->resourceMgr()->stringValue("ExternalBrowser", platform)).arg(aHelpFileName),
591 QObject::tr("BUT_OK"));
595 //=================================================================================
596 // function : onSelectionChanged()
597 // purpose : Called when selection is changed
598 //=================================================================================
599 void VisuGUI_ClippingDlg::onSelectionChanged()
601 if(SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI)){
603 VISU::TSelectionInfo aSelectionInfo = VISU::GetSelectedObjects(myVisuGUI);
604 if(aSelectionInfo.empty())
607 VISU::TSelectionItem aSelectionItem = aSelectionInfo.front();
608 VISU::Base_i* aBase = aSelectionItem.myObjectInfo.myBase;
612 Handle(SALOME_InteractiveObject) anIO = aSelectionItem.myIO;
616 SetPrs3d(dynamic_cast<VISU::Prs3d_i*>(aBase));
618 std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
621 CORBA::Float anOffset[3];
622 myPrs3d->GetOffset(anOffset[0],anOffset[1],anOffset[2]);
624 vtkIdType anId = 0, anEnd = myPrs3d->GetNumberOfClippingPlanes();
625 for (; anId < anEnd; anId++) {
626 if (vtkImplicitFunction* aFunction = myPrs3d->GetClippingPlane(anId)) {
627 if (OrientedPlane* aPlane = OrientedPlane::SafeDownCast(aFunction)) {
628 OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow);
629 VISU::TVTKPlane aTVTKPlane(anOrientedPlane);
630 anOrientedPlane->Delete();
631 aTVTKPlane->ShallowCopy(aPlane);
632 aTVTKPlane->myActor->SetPosition(anOffset[0],anOffset[1],anOffset[2]);
633 myPlanes.push_back(aTVTKPlane);
638 std::for_each(myPlanes.begin(),myPlanes.end(),
639 TSetVisiblity(PreviewCheckBox->isChecked()));
642 // enable/disable IJK tab
643 TabPane->setTabEnabled(WidgetIJKTab, isStructured());
645 VISU::RenderViewWindow(aViewWindow);
649 //=================================================================================
650 // function : onSelectPlane()
652 //=================================================================================
653 void VisuGUI_ClippingDlg::onSelectPlane(int theIndex)
655 if (!myPrs3d || myPlanes.empty())
658 OrientedPlane* aPlane = myPlanes[theIndex].GetPointer();
661 VISU::Orientation anOrientation = aPlane->GetOrientation();
664 double aRot[2] = {aPlane->myAngle[0], aPlane->myAngle[1]};
666 // Set plane parameters in the dialog
667 myIsSelectPlane = true;
668 setDistance(aPlane->GetDistance());
669 setRotation(aRot[0], aRot[1]);
671 switch (anOrientation) {
672 case VISU::XY: item = 0; break;
673 case VISU::YZ: item = 1; break;
674 case VISU::ZX: item = 2; break;
676 ComboBoxOrientation->setCurrentItem(item);
678 bool isIJK = (TabPane->currentPage() == WidgetIJKTab);
680 setIJKByNonStructured();
682 onSelectOrientation(item);
684 myIsSelectPlane = false;
687 //=================================================================================
688 // function : ClickOnNew()
690 //=================================================================================
691 void VisuGUI_ClippingDlg::ClickOnNew()
693 VISU::TSelectionInfo aSelectionInfo = VISU::GetSelectedObjects(myVisuGUI);
694 if(aSelectionInfo.empty())
697 const VISU::TSelectionItem& aSelectionItem = aSelectionInfo[0];
698 if(!aSelectionItem.myObjectInfo.myBase)
701 SetCurrentPlaneParam();
706 if (SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI)) {
707 OrientedPlane* aPlane = OrientedPlane::New(aViewWindow);
708 VISU::TVTKPlane aTVTKPlane(aPlane);
709 myPlanes.push_back(aTVTKPlane);
711 CORBA::Float anOffset[3];
712 myPrs3d->GetOffset(anOffset[0],anOffset[1],anOffset[2]);
713 aTVTKPlane->myActor->SetPosition(anOffset[0],anOffset[1],anOffset[2]);
715 if (PreviewCheckBox->isChecked())
716 aTVTKPlane->myActor->VisibilityOn();
719 SetCurrentPlaneParam();
723 //=================================================================================
724 // function : ClickOnDelete()
726 //=================================================================================
727 void VisuGUI_ClippingDlg::ClickOnDelete()
729 if (!myPrs3d || myPlanes.empty())
732 int aPlaneIndex = ComboBoxPlanes->currentItem();
734 VISU::TPlanes::iterator anIter = myPlanes.begin() + aPlaneIndex;
735 anIter->GetPointer()->myActor->SetVisibility(false);
736 myPlanes.erase(anIter);
738 if(AutoApplyCheckBox->isChecked())
742 if (SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI))
743 VISU::RenderViewWindow(aViewWindow);
746 //=================================================================================
747 // function : onSelectOrientation()
749 //=================================================================================
750 void VisuGUI_ClippingDlg::onSelectOrientation(int theItem)
752 if (myPlanes.empty())
756 TextLabelRot1->setText(tr("LBL_ROTATION_YZ"));
757 TextLabelRot2->setText(tr("LBL_ROTATION_XZ"));
759 else if (theItem == 1) {
760 TextLabelRot1->setText(tr("LBL_ROTATION_ZX"));
761 TextLabelRot2->setText(tr("LBL_ROTATION_YX"));
763 else if (theItem == 2) {
764 TextLabelRot1->setText(tr("LBL_ROTATION_XY"));
765 TextLabelRot2->setText(tr("LBL_ROTATION_ZY"));
768 if((QComboBox*)sender() == ComboBoxOrientation)
769 SetCurrentPlaneParam();
772 //=================================================================================
773 // function : Sinchronize()
774 // purpose : update control values according to plane selection
775 //=================================================================================
776 void VisuGUI_ClippingDlg::Sinchronize()
778 int aNbPlanes = myPlanes.size();
779 ComboBoxPlanes->clear();
782 for (int i = 1; i<=aNbPlanes; i++) {
783 aName = QString(tr("PLANES_COMBO_ITEM_i")).arg(i);
784 ComboBoxPlanes->insertItem(aName);
787 int aPos = ComboBoxPlanes->count() - 1;
788 ComboBoxPlanes->setCurrentItem(aPos);
790 bool anIsControlsEnable = (aPos >= 0);
791 if (anIsControlsEnable) {
794 ComboBoxPlanes->insertItem(tr("PLANES_COMBO_ITEM_no"));
795 SpinBoxRot1->setValue(0.0);
796 SpinBoxRot2->setValue(0.0);
797 SpinBoxDistance->setValue(0.5);
800 buttonDelete ->setEnabled(anIsControlsEnable);
801 buttonApply ->setEnabled(anIsControlsEnable);
802 PreviewCheckBox ->setEnabled(anIsControlsEnable);
803 AutoApplyCheckBox ->setEnabled(anIsControlsEnable);
805 ComboBoxOrientation ->setEnabled(anIsControlsEnable);
806 SpinBoxDistance ->setEnabled(anIsControlsEnable);
807 SpinBoxRot1 ->setEnabled(anIsControlsEnable);
808 SpinBoxRot2 ->setEnabled(anIsControlsEnable);
810 ButtonGroupIJKAxis ->setEnabled(anIsControlsEnable);
811 SpinBoxIJKIndex ->setEnabled(anIsControlsEnable);
812 CheckBoxIJKPlaneReverse->setEnabled(anIsControlsEnable);
813 //ENK: 23.11.2006 - PAL13176 - EDF228 VISU : Enhancement of structured datas processing
815 VISU_PipeLine* aPipeLine = myPrs3d->GetPipeLine();
816 VISU::PIDMapper anIDMapper = aPipeLine->GetIDMapper();
817 if(anIDMapper->IsStructured()){
818 VISU::TIdTypeVector aVec = anIDMapper->GetStructure();
821 ButtonGroupIJKAxis->find(0)->setEnabled(true);
822 ButtonGroupIJKAxis->find(1)->setEnabled(false);
823 ButtonGroupIJKAxis->find(2)->setEnabled(false);
826 ButtonGroupIJKAxis->find(0)->setEnabled(true);
827 ButtonGroupIJKAxis->find(1)->setEnabled(true);
828 ButtonGroupIJKAxis->find(2)->setEnabled(false);
831 ButtonGroupIJKAxis->find(0)->setEnabled(true);
832 ButtonGroupIJKAxis->find(1)->setEnabled(true);
833 ButtonGroupIJKAxis->find(2)->setEnabled(true);
841 //=================================================================================
842 // function : setRotation()
844 //=================================================================================
845 void VisuGUI_ClippingDlg::setRotation(const double theRot1, const double theRot2)
847 SpinBoxRot1->setValue(theRot1);
848 SpinBoxRot2->setValue(theRot2);
851 //=================================================================================
852 // function : SetCurrentPlaneParam()
854 //=================================================================================
855 void VisuGUI_ClippingDlg::SetCurrentPlaneParam()
857 if (myPlanes.empty() || myIsSelectPlane)
860 int aCurPlaneIndex = ComboBoxPlanes->currentItem();
862 OrientedPlane* aPlane = myPlanes[aCurPlaneIndex].GetPointer();
864 vtkFloatingPointType aNormal[3];
865 VISU::Orientation anOrientation;
866 vtkFloatingPointType aDir[3][3] = {{0, 0, 0}, {0, 0, 0}};
868 static double aCoeff = vtkMath::Pi()/180.0;
870 vtkFloatingPointType aRot[2] = {getRotation1(), getRotation2()};
871 aPlane->myAngle[0] = aRot[0];
872 aPlane->myAngle[1] = aRot[1];
874 vtkFloatingPointType anU[2] = {cos(aCoeff*aRot[0]), cos(aCoeff*aRot[1])};
875 vtkFloatingPointType aV[2] = {sqrt(1.0-anU[0]*anU[0]), sqrt(1.0-anU[1]*anU[1])};
876 aV[0] = aRot[0] > 0? aV[0]: -aV[0];
877 aV[1] = aRot[1] > 0? aV[1]: -aV[1];
879 switch (ComboBoxOrientation->currentItem()) {
881 anOrientation = VISU::XY;
891 anOrientation = VISU::YZ;
901 anOrientation = VISU::ZX;
912 vtkMath::Cross(aDir[1],aDir[0],aNormal);
913 vtkMath::Normalize(aNormal);
914 vtkMath::Cross(aNormal,aDir[1],aDir[0]);
917 aPlane->SetOrientation(anOrientation);
918 aPlane->SetDistance(getDistance());
920 myPrs3d->SetPlaneParam(aNormal, 1. - getDistance(), aPlane);
922 vtkDataSet* aDataSet = myPrs3d->GetInput();
923 vtkFloatingPointType *aPnt = aDataSet->GetCenter();
925 vtkFloatingPointType* anOrigin = aPlane->GetOrigin();
926 vtkFloatingPointType aDel = aDataSet->GetLength()/2.0;
928 vtkFloatingPointType aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel},
929 {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}};
930 vtkFloatingPointType aParam, aPnt0[3], aPnt1[3], aPnt2[3];
932 vtkFloatingPointType aPnt01[3] = {aPnt[0] - aDelta[0][0] - aDelta[1][0],
933 aPnt[1] - aDelta[0][1] - aDelta[1][1],
934 aPnt[2] - aDelta[0][2] - aDelta[1][2]};
935 vtkFloatingPointType aPnt02[3] = {aPnt01[0] + aNormal[0],
936 aPnt01[1] + aNormal[1],
937 aPnt01[2] + aNormal[2]};
938 vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0);
940 vtkFloatingPointType aPnt11[3] = {aPnt[0] - aDelta[0][0] + aDelta[1][0],
941 aPnt[1] - aDelta[0][1] + aDelta[1][1],
942 aPnt[2] - aDelta[0][2] + aDelta[1][2]};
943 vtkFloatingPointType aPnt12[3] = {aPnt11[0] + aNormal[0],
944 aPnt11[1] + aNormal[1],
945 aPnt11[2] + aNormal[2]};
946 vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1);
948 vtkFloatingPointType aPnt21[3] = {aPnt[0] + aDelta[0][0] - aDelta[1][0],
949 aPnt[1] + aDelta[0][1] - aDelta[1][1],
950 aPnt[2] + aDelta[0][2] - aDelta[1][2]};
951 vtkFloatingPointType aPnt22[3] = {aPnt21[0] + aNormal[0],
952 aPnt21[1] + aNormal[1],
953 aPnt21[2] + aNormal[2]};
954 vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2);
956 vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource;
957 aPlaneSource->SetNormal(aNormal[0],aNormal[1],aNormal[2]);
958 aPlaneSource->SetOrigin(aPnt0[0],aPnt0[1],aPnt0[2]);
959 aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]);
960 aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]);
962 if (AutoApplyCheckBox->isChecked())
965 if (SVTK_ViewWindow* vw = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI))
966 VISU::RenderViewWindow(vw);
969 //=================================================================================
970 // function : onTabChanged
972 //=================================================================================
973 void VisuGUI_ClippingDlg::onTabChanged(QWidget* newTab)
975 if (newTab == WidgetIJKTab) // IJK
976 setIJKByNonStructured();
978 // set correct labels of rotation spin boxes
979 onSelectOrientation(ComboBoxOrientation->currentItem());
983 //=================================================================================
984 // function : SetCurrentPlaneIJKParam
985 // purpose : set non structured parameters by IJK parameters
986 //=================================================================================
987 void VisuGUI_ClippingDlg::SetCurrentPlaneIJKParam()
989 if (myPlanes.empty() || myIsSelectPlane || !WidgetIJKTab->isEnabled())
992 VISU::Result_i* result = myPrs3d ? myPrs3d->GetCResult() : 0;
997 int i, axId = ButtonGroupIJKAxis->id (ButtonGroupIJKAxis->selected());
998 VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) axId;
1000 CORBA::String_var aMeshName = myPrs3d->GetMeshName();
1001 const vector<vtkFloatingPointType> * values =
1002 result->GetAxisInfo(aMeshName.in(), axis, dir);
1007 int index = SpinBoxIJKIndex->value();
1008 vtkFloatingPointType distance = 0;
1009 if (index < values->size())
1010 distance = (*values)[ index ];
1012 // find id of axis closest to dir
1013 // 0 || X-Y - axis Z
1014 // 1 || Y-Z - azis X
1015 // 2 || Z-X - axiz Y
1016 double cos[3] = { gp::DZ() * dir, gp::DX() * dir, gp::DY() * dir };
1018 for (i = 0; i < 3; ++i) {
1019 if (Abs(cos[ i ]) > Abs (maxCos)) {
1024 // find rotation angles
1025 vtkFloatingPointType angle[2];
1027 (axId == 0) ? 2 : axId - 1,
1028 (axId == 2) ? 0 : axId + 1
1030 static double aCoeff = 180.0/vtkMath::Pi();
1031 for (i = 0; i < 2; ++i) {
1032 vtkFloatingPointType cosin = cos[ rotId[ i ]];
1035 angle[ i ] = asin(cosin) * aCoeff;
1037 // angle[ i ] += 180. * (angle[ i ] < 0 ? 1. : -1.);
1039 if (CheckBoxIJKPlaneReverse->isChecked()) {
1040 angle[ 0 ] += 180. * (angle[ 0 ] < 0 ? 1. : -1.);
1041 distance = 1. - distance;
1044 // distance = 1. - distance;
1047 myIsSelectPlane = true;
1048 ComboBoxOrientation->setCurrentItem(axId);
1049 setRotation(-angle[0], -angle[1]);
1050 setDistance(distance);
1051 myIsSelectPlane = false;
1053 SetCurrentPlaneParam();
1056 //=================================================================================
1057 // function : setIJKByNonStructured
1058 // purpose : convert current non structured parameters to structured ones
1059 //=================================================================================
1060 void VisuGUI_ClippingDlg::setIJKByNonStructured()
1062 if (!myPrs3d || myPlanes.empty() || !myPrs3d->GetCResult())
1066 int planeIndex = ComboBoxPlanes->currentItem();
1067 OrientedPlane* plane = myPlanes[ planeIndex ].GetPointer();
1068 vtkPlaneSource* planeSource = plane->myPlaneSource;
1069 vtkFloatingPointType * planeNormal = planeSource->GetNormal();
1070 gp_Dir normal(planeNormal[0], planeNormal[1], planeNormal[2]);
1072 // find a grid axis most co-directed with plane normal
1073 // and cartesian axis most co-directed with plane normal
1074 int i, maxAx = 0, gridAxId = 0;
1075 gp_Dir dir, gridDir;
1077 const vector<vtkFloatingPointType> *curValues, *values = 0;
1078 VISU::Result_i* result = myPrs3d->GetCResult();
1080 VISU_PipeLine* aPipeLine = myPrs3d->GetPipeLine();
1081 VISU::PIDMapper anIDMapper = aPipeLine->GetIDMapper();
1082 if(anIDMapper->IsStructured() && !anIDMapper->myType)
1083 aNbAxes = (anIDMapper->GetStructure()).size();
1084 for (i = 0; i < aNbAxes; ++i) {
1085 VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) i;
1086 CORBA::String_var aMeshName = myPrs3d->GetMeshName();
1087 curValues = result->GetAxisInfo(aMeshName.in(), axis, dir);
1089 double dot = normal * dir;
1090 //ENK: 23.11.2006 - PAL13176
1096 } else if (Abs(dot) >= Abs(maxDot)) {
1104 if (Abs (planeNormal[ maxAx ]) < Abs (planeNormal[ i ]))
1107 gp_XYZ axDir(0,0,0);
1108 axDir.SetCoord(maxAx + 1, 1.);
1111 double v = SpinBoxDistance->value();
1113 // bool reverse = (normal * axDir < 0); // normal and axis are opposite
1114 // if (gridDir * axDir < 0) // grid dir and axis are opposite
1115 // reverse = !reverse;
1118 for (i = 0; i < values->size(); ++i)
1119 if ((*values)[ i ] > v)
1121 if (i == values->size())
1123 if (i != 0 && (*values)[ i ] - v > v - (*values)[ i - 1])
1126 // set control values
1127 myIsSelectPlane = true;
1128 CheckBoxIJKPlaneReverse->setChecked(normal * axDir < 0);
1129 SpinBoxIJKIndex->setValue(i);
1130 ButtonGroupIJKAxis->setButton(gridAxId);
1131 onIJKAxisChanged(gridAxId); // update label and range of index
1132 myIsSelectPlane = false;
1134 SetCurrentPlaneIJKParam();
1137 //=================================================================================
1138 // function : isStructured
1139 // purpose : return true if mesh is structured
1140 //=================================================================================
1141 bool VisuGUI_ClippingDlg::isStructured() const
1143 VISU::Result_i* result = myPrs3d ? myPrs3d->GetCResult() : 0;
1146 return result->GetAxisInfo(myPrs3d->GetCMeshName(),
1147 VISU::Result_i::AXIS_X,
1153 //=================================================================================
1154 // function : onIJKAxisChanged
1155 // purpose : update Index range and call SetCurrentPlaneParam()
1156 //=================================================================================
1157 void VisuGUI_ClippingDlg::onIJKAxisChanged(int axisId)
1161 VISU::Result_i* result = myPrs3d ? myPrs3d->GetCResult() : 0;
1163 VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) axisId;
1165 CORBA::String_var aMeshName = myPrs3d->GetMeshName();
1166 const vector<vtkFloatingPointType> * indices = result->GetAxisInfo(aMeshName.in(),
1169 maxIndex = indices->size() - 1;
1171 QString text = tr("LBL_IJK_INDEX_TO_arg").arg(maxIndex);
1172 TextLabelIJKIndex->setText(text);
1173 SpinBoxIJKIndex->setRange(0, maxIndex);
1175 if (SpinBoxIJKIndex->value() > maxIndex)
1176 SpinBoxIJKIndex->setValue(0);
1178 SetCurrentPlaneIJKParam();
1181 //=================================================================================
1182 // function : OnPreviewToggle()
1184 //=================================================================================
1185 void VisuGUI_ClippingDlg::OnPreviewToggle (bool theIsToggled)
1187 std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(theIsToggled));
1188 if (SVTK_ViewWindow* vw = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI))
1189 VISU::RenderViewWindow(vw);
1193 //=================================================================================
1194 // function : keyPressEvent()
1196 //=================================================================================
1197 void VisuGUI_ClippingDlg::keyPressEvent( QKeyEvent* e )
1199 QDialog::keyPressEvent( e );
1200 if ( e->isAccepted() )
1203 if ( e->key() == Key_F1 )
1210 void VisuGUI_ClippingDlg::SetPrs3d(VISU::Prs3d_i* thePrs)
1212 if(thePrs != myPrs3d){