2 #include "VisuGUI_ClippingDlg.h"
5 #include "VisuGUI_Tools.h"
7 #include "VISU_Prs3d_i.hh"
8 #include "VISU_Result_i.hh"
10 #include "VISU_PipeLine.hxx"
12 #include "LightApp_SelectionMgr.h"
14 #include "SVTK_ViewWindow.h"
16 #include "SUIT_Session.h"
17 #include "SUIT_Desktop.h"
18 #include "SUIT_MessageBox.h"
19 #include "SUIT_ResourceMgr.h"
20 #include "SUIT_OverrideCursor.h"
22 #include "SALOME_Actor.h"
26 #include <qpushbutton.h>
27 #include <qcombobox.h>
28 #include <qcheckbox.h>
30 #include <qgroupbox.h>
31 #include <qvalidator.h>
32 #include <qtabwidget.h>
33 #include <qhbuttongroup.h>
34 #include <qradiobutton.h>
39 #include <vtkCamera.h>
40 #include <vtkRenderer.h>
41 #include <vtkDataSet.h>
42 #include <vtkDataSetMapper.h>
43 #include <vtkImplicitFunction.h>
44 #include <vtkPlaneSource.h>
45 #include <vtkPolyData.h>
46 #include <vtkUnstructuredGrid.h>
54 float GetFloat (const QString& theValue, float theDefault)
56 if (theValue.isEmpty()) return theDefault;
57 SUIT_ResourceMgr* aResourceMgr = VISU::GetResourceMgr();
58 QString aValue = aResourceMgr->stringValue("VISU",theValue);
59 if (aValue.isEmpty()) return theDefault;
60 return aValue.toFloat();
63 void RenderViewWindow (SVTK_ViewWindow* vw)
66 vw->getRenderer()->ResetCameraClippingRange();
71 void RangeStepAndValidator (QtxDblSpinBox* theSpinBox, double min, double max,
72 double step, unsigned short decimals)
74 theSpinBox->setRange(min, max);
75 theSpinBox->setLineStep(step);
76 ((QDoubleValidator*)theSpinBox->validator())->setRange(min, max, decimals);
80 //=================================================================================
81 //class : OrientedPlane
83 //=================================================================================
84 class OrientedPlane: public vtkPlane
86 SVTK_ViewWindow* myViewWindow;
88 vtkDataSetMapper* myMapper;
91 static OrientedPlane * New() {
92 return new OrientedPlane();
94 static OrientedPlane * New (SVTK_ViewWindow* vw) {
95 return new OrientedPlane(vw);
97 vtkTypeMacro(OrientedPlane, vtkPlane);
100 VISU::Orientation myOrientation;
104 vtkPlaneSource* myPlaneSource;
105 SALOME_Actor *myActor;
107 void SetOrientation(VISU::Orientation theOrientation) {myOrientation = theOrientation;}
108 VISU::Orientation GetOrientation() {return myOrientation;}
110 void SetDistance(float theDistance) {myDistance = theDistance;}
111 float GetDistance() {return myDistance;}
113 void ShallowCopy(OrientedPlane* theOrientedPlane){
114 SetNormal(theOrientedPlane->GetNormal());
115 SetOrigin(theOrientedPlane->GetOrigin());
117 myOrientation = theOrientedPlane->GetOrientation();
118 myDistance = theOrientedPlane->GetDistance();
120 myAngle[0] = theOrientedPlane->myAngle[0];
121 myAngle[1] = theOrientedPlane->myAngle[1];
123 myPlaneSource->SetNormal(theOrientedPlane->myPlaneSource->GetNormal());
124 myPlaneSource->SetOrigin(theOrientedPlane->myPlaneSource->GetOrigin());
125 myPlaneSource->SetPoint1(theOrientedPlane->myPlaneSource->GetPoint1());
126 myPlaneSource->SetPoint2(theOrientedPlane->myPlaneSource->GetPoint2());
130 OrientedPlane(SVTK_ViewWindow* vw):
131 myOrientation(VISU::XY),
136 myViewWindow->AddActor(myActor);
140 myOrientation(VISU::XY),
148 myPlaneSource = vtkPlaneSource::New();
150 myAngle[0] = myAngle[1] = 0.0;
152 // Create and display actor
153 myMapper = vtkDataSetMapper::New();
154 myMapper->SetInput(myPlaneSource->GetOutput());
156 myActor = SALOME_Actor::New();
157 myActor->VisibilityOff();
158 myActor->PickableOff();
159 myActor->SetInfinitive(true);
160 myActor->SetMapper(myMapper);
162 vtkProperty* aProp = vtkProperty::New();
165 SUIT_ResourceMgr* aResourceMgr = VISU::GetResourceMgr();
167 QColor aFillColor = aResourceMgr->colorValue("SMESH", "fill_color", QColor(0, 170, 255));
168 anRGB[0] = aFillColor.red()/255.;
169 anRGB[1] = aFillColor.green()/255.;
170 anRGB[2] = aFillColor.blue()/255.;
171 aProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
172 aProp->SetOpacity(0.75);
173 myActor->SetProperty(aProp);
176 vtkProperty* aBackProp = vtkProperty::New();
177 QColor aBackFaceColor = aResourceMgr->colorValue("SMESH", "backface_color", QColor(0, 0, 255));//@
178 anRGB[0] = aBackFaceColor.red()/255.;
179 anRGB[1] = aBackFaceColor.green()/255.;
180 anRGB[2] = aBackFaceColor.blue()/255.;
181 aBackProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
182 aBackProp->SetOpacity(0.75);
183 myActor->SetBackfaceProperty(aBackProp);
190 myViewWindow->RemoveActor(myActor);
194 myMapper->RemoveAllInputs();
197 myPlaneSource->UnRegisterAllOutputs();
198 myPlaneSource->Delete();
203 OrientedPlane(const OrientedPlane&);
204 void operator=(const OrientedPlane&);
207 struct TSetVisiblity {
208 TSetVisiblity(int theIsVisible): myIsVisible(theIsVisible){}
209 void operator()(VISU::TVTKPlane& theOrientedPlane){
210 theOrientedPlane->myActor->SetVisibility(myIsVisible);
215 //=================================================================================
216 // class : VisuGUI_ClippingDlg()
219 //=================================================================================
220 VisuGUI_ClippingDlg::VisuGUI_ClippingDlg (VisuGUI* theModule,
224 : QDialog(VISU::GetDesktop(theModule), name, modal, WStyle_Customize |
225 WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
226 mySelectionMgr(VISU::GetSelectionMgr(theModule)),
230 setName("VisuGUI_ClippingDlg");
231 setCaption(tr("TITLE"));
232 setSizeGripEnabled(TRUE);
233 QGridLayout* VisuGUI_ClippingDlgLayout = new QGridLayout(this);
234 VisuGUI_ClippingDlgLayout->setSpacing(6);
235 VisuGUI_ClippingDlgLayout->setMargin(11);
237 // Controls for selecting, creating, deleting planes
238 QGroupBox* GroupPlanes = new QGroupBox (this, "GroupPlanes");
239 GroupPlanes->setTitle(tr("GRP_PLANES"));
240 GroupPlanes->setColumnLayout(0, Qt::Vertical);
241 GroupPlanes->layout()->setSpacing(0);
242 GroupPlanes->layout()->setMargin(0);
243 QGridLayout* GroupPlanesLayout = new QGridLayout (GroupPlanes->layout());
244 GroupPlanesLayout->setAlignment(Qt::AlignTop);
245 GroupPlanesLayout->setSpacing(6);
246 GroupPlanesLayout->setMargin(11);
248 ComboBoxPlanes = new QComboBox (GroupPlanes, "ComboBoxPlanes");
249 GroupPlanesLayout->addWidget(ComboBoxPlanes, 0, 0);
251 QSpacerItem* spacerGP = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
252 GroupPlanesLayout->addItem(spacerGP, 0, 1);
254 buttonNew = new QPushButton (GroupPlanes, "buttonNew");
255 buttonNew->setText(tr("BUT_NEW"));
256 GroupPlanesLayout->addWidget(buttonNew, 0, 2);
258 buttonDelete = new QPushButton(GroupPlanes, "buttonDelete");
259 buttonDelete->setText(tr("BUT_DELETE"));
260 GroupPlanesLayout->addWidget(buttonDelete, 0, 3);
262 // Controls for defining plane parameters
265 QGroupBox* GroupParameters = new QGroupBox(this, "GroupParameters");
266 GroupParameters->setTitle(tr("GRP_PARAMETERS"));
267 GroupParameters->setColumnLayout(0, Qt::Vertical);
268 GroupParameters->layout()->setSpacing(0);
269 GroupParameters->layout()->setMargin(0);
270 QGridLayout* GroupParametersLayout = new QGridLayout (GroupParameters->layout());
271 GroupParametersLayout->setAlignment(Qt::AlignTop);
272 GroupParametersLayout->setSpacing(6);
273 GroupParametersLayout->setMargin(11);
275 TabPane = new QTabWidget (GroupParameters);
276 TabPane->addTab(createParamsTab() , tr("TAB_NON_STRUCTURED"));
277 TabPane->addTab(createIJKParamsTab(), tr("TAB_IJK_STRUCTURED"));
278 GroupParametersLayout->addWidget(TabPane, 0, 0);
280 // "Show preview" and "Auto Apply" check boxes
282 PreviewCheckBox = new QCheckBox (tr("SHOW_PREVIEW_CHK"), this);
283 PreviewCheckBox->setChecked(true);
285 AutoApplyCheckBox = new QCheckBox (tr("AUTO_APPLY_CHK"), this);
286 AutoApplyCheckBox->setChecked(false);
288 // Controls for "Ok", "Apply" and "Close" button
289 QGroupBox* GroupButtons = new QGroupBox (this, "GroupButtons");
290 GroupButtons->setSizePolicy(QSizePolicy((QSizePolicy::SizeType)7,
291 (QSizePolicy::SizeType)0, 0, 0,
292 GroupButtons->sizePolicy().hasHeightForWidth()));
293 GroupButtons->setGeometry(QRect(10, 10, 281, 48));
294 //GroupButtons->setTitle(tr(""));
295 GroupButtons->setColumnLayout(0, Qt::Vertical);
296 GroupButtons->layout()->setSpacing(0);
297 GroupButtons->layout()->setMargin(0);
298 QGridLayout* GroupButtonsLayout = new QGridLayout (GroupButtons->layout());
299 GroupButtonsLayout->setAlignment(Qt::AlignTop);
300 GroupButtonsLayout->setSpacing(6);
301 GroupButtonsLayout->setMargin(11);
302 buttonCancel = new QPushButton (GroupButtons, "buttonCancel");
303 buttonCancel->setText(tr("BUT_CLOSE"));
304 buttonCancel->setAutoDefault(TRUE);
305 GroupButtonsLayout->addWidget(buttonCancel, 0, 3);
306 buttonApply = new QPushButton (GroupButtons, "buttonApply");
307 buttonApply->setText(tr("BUT_APPLY"));
308 buttonApply->setAutoDefault(TRUE);
309 GroupButtonsLayout->addWidget(buttonApply, 0, 1);
310 QSpacerItem* spacer_9 = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
311 GroupButtonsLayout->addItem(spacer_9, 0, 2);
312 buttonOk = new QPushButton (GroupButtons, "buttonOk");
313 buttonOk->setText(tr("BUT_OK"));
314 buttonOk->setAutoDefault(TRUE);
315 buttonOk->setDefault(TRUE);
316 GroupButtonsLayout->addWidget(buttonOk, 0, 0);
318 VisuGUI_ClippingDlgLayout->addMultiCellWidget(GroupPlanes, 0, 0, 0, 1);
319 VisuGUI_ClippingDlgLayout->addMultiCellWidget(GroupParameters, 1, 1, 0, 1);
320 VisuGUI_ClippingDlgLayout->addWidget(PreviewCheckBox, 2, 0);
321 VisuGUI_ClippingDlgLayout->addWidget(AutoApplyCheckBox, 2, 1);
322 VisuGUI_ClippingDlgLayout->addMultiCellWidget(GroupButtons, 3, 3, 0, 1);
325 VISU::RangeStepAndValidator(SpinBoxDistance, 0.0, 1.0, 0.01, 3);
326 VISU::RangeStepAndValidator(SpinBoxRot1, -180.0, 180.0, 1, 3);
327 VISU::RangeStepAndValidator(SpinBoxRot2, -180.0, 180.0, 1, 3);
329 ComboBoxOrientation->insertItem(tr("PARALLEL_XOY_COMBO_ITEM"));
330 ComboBoxOrientation->insertItem(tr("PARALLEL_YOZ_COMBO_ITEM"));
331 ComboBoxOrientation->insertItem(tr("PARALLEL_ZOX_COMBO_ITEM"));
333 SpinBoxDistance->setValue(0.5);
336 myIsSelectPlane = false;
337 onSelectionChanged();
339 // signals and slots connections :
340 connect(ComboBoxPlanes , SIGNAL(activated(int)) , this, SLOT(onSelectPlane(int)));
341 connect(buttonNew , SIGNAL(clicked()) , this, SLOT(ClickOnNew()));
342 connect(buttonDelete , SIGNAL(clicked()) , this, SLOT(ClickOnDelete()));
343 connect(ComboBoxOrientation , SIGNAL(activated(int)) , this, SLOT(onSelectOrientation(int)));
344 connect(SpinBoxDistance , SIGNAL(valueChanged(double)) , this, SLOT(SetCurrentPlaneParam()));
345 connect(SpinBoxRot1 , SIGNAL(valueChanged(double)) , this, SLOT(SetCurrentPlaneParam()));
346 connect(SpinBoxRot2 , SIGNAL(valueChanged(double)) , this, SLOT(SetCurrentPlaneParam()));
347 connect(ButtonGroupIJKAxis , SIGNAL(clicked(int)) , this, SLOT(onIJKAxisChanged(int)));
348 connect(SpinBoxIJKIndex , SIGNAL(valueChanged(int)) , this, SLOT(SetCurrentPlaneIJKParam()));
349 connect(CheckBoxIJKPlaneReverse, SIGNAL(toggled(bool)) , this, SLOT(SetCurrentPlaneIJKParam()));
350 connect(TabPane , SIGNAL(currentChanged (QWidget*)), this, SLOT(onTabChanged(QWidget*)));
352 connect(PreviewCheckBox , SIGNAL(toggled(bool)), this, SLOT(OnPreviewToggle(bool)));
353 connect(AutoApplyCheckBox, SIGNAL(toggled(bool)), this, SLOT(ClickOnApply()));
355 connect(buttonOk , SIGNAL(clicked()), this, SLOT(ClickOnOk()));
356 connect(buttonApply , SIGNAL(clicked()), this, SLOT(ClickOnApply()));
357 connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()));
359 connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionChanged()));
364 //=================================================================================
365 // function : ~VisuGUI_ClippingDlg()
367 //=================================================================================
368 VisuGUI_ClippingDlg::~VisuGUI_ClippingDlg()
370 // no need to delete child widgets, Qt does it all for us
371 std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
372 VISU::RenderViewWindow(VISU::GetViewWindow(myVisuGUI));
375 //=================================================================================
376 // function : createParamsTab
378 //=================================================================================
379 QWidget* VisuGUI_ClippingDlg::createParamsTab()
381 QFrame* GroupParameters = new QFrame(this);
382 QGridLayout* GroupParametersLayout = new QGridLayout(GroupParameters);
383 GroupParametersLayout->setAlignment(Qt::AlignTop);
384 GroupParametersLayout->setSpacing(6);
385 GroupParametersLayout->setMargin(11);
387 TextLabelOrientation = new QLabel(GroupParameters, "TextLabelOrientation");
388 TextLabelOrientation->setText(tr("LBL_ORIENTATION"));
389 GroupParametersLayout->addWidget(TextLabelOrientation, 0, 0);
391 ComboBoxOrientation = new QComboBox(GroupParameters, "ComboBoxOrientation");
392 GroupParametersLayout->addWidget(ComboBoxOrientation, 0, 1);
394 TextLabelDistance = new QLabel(GroupParameters, "TextLabelDistance");
395 TextLabelDistance->setText(tr("LBL_DISTANCE"));
396 GroupParametersLayout->addWidget(TextLabelDistance, 1, 0);
398 SpinBoxDistance = new QtxDblSpinBox(GroupParameters, "SpinBoxDistance");
399 GroupParametersLayout->addWidget(SpinBoxDistance, 1, 1);
401 TextLabelRot1 = new QLabel(GroupParameters, "TextLabelRot1");
402 TextLabelRot1->setText(tr("LBL_ROTATION_YZ"));
403 GroupParametersLayout->addWidget(TextLabelRot1, 2, 0);
405 SpinBoxRot1 = new QtxDblSpinBox(GroupParameters, "SpinBoxRot1");
406 GroupParametersLayout->addWidget(SpinBoxRot1, 2, 1);
408 TextLabelRot2 = new QLabel(GroupParameters, "TextLabelRot2");
409 TextLabelRot2->setText(tr("LBL_ROTATION_XZ"));
410 GroupParametersLayout->addWidget(TextLabelRot2, 3, 0);
412 SpinBoxRot2 = new QtxDblSpinBox(GroupParameters, "SpinBoxRot2");
413 GroupParametersLayout->addWidget(SpinBoxRot2, 3, 1);
415 return GroupParameters;
418 //=================================================================================
419 // function : createIJKParamsTab
421 //=================================================================================
422 QWidget* VisuGUI_ClippingDlg::createIJKParamsTab()
425 WidgetIJKTab = new QFrame(this);
426 QGridLayout* IJKParametersLayout = new QGridLayout(WidgetIJKTab);
427 IJKParametersLayout->setAlignment(Qt::AlignTop);
428 IJKParametersLayout->setSpacing(6);
429 IJKParametersLayout->setMargin(11);
432 ButtonGroupIJKAxis = new QHButtonGroup (tr("GRP_IJK_AXIS"), WidgetIJKTab);
433 new QRadioButton (tr("I_RADIO_BTN"), ButtonGroupIJKAxis); // 0
434 new QRadioButton (tr("J_RADIO_BTN"), ButtonGroupIJKAxis); // 1
435 new QRadioButton (tr("K_RADIO_BTN"), ButtonGroupIJKAxis); // 2
436 ButtonGroupIJKAxis->setButton(0);
439 TextLabelIJKIndex = new QLabel(WidgetIJKTab, "TextLabelIJKIndex");
440 TextLabelIJKIndex->setText(tr("LBL_IJK_INDEX"));
441 SpinBoxIJKIndex = new QSpinBox(WidgetIJKTab, "SpinBoxIJKIndex");
444 CheckBoxIJKPlaneReverse = new QCheckBox (tr("REVERSE_NORMAL_CHK"), WidgetIJKTab);
445 CheckBoxIJKPlaneReverse->setChecked(false);
447 IJKParametersLayout->addMultiCellWidget(ButtonGroupIJKAxis, 0, 0, 0, 1);
448 IJKParametersLayout->addWidget(TextLabelIJKIndex, 1, 0);
449 IJKParametersLayout->addWidget(SpinBoxIJKIndex, 1, 1);
450 IJKParametersLayout->addWidget(CheckBoxIJKPlaneReverse, 2, 0);
455 //=================================================================================
456 // function : ClickOnApply()
458 //=================================================================================
459 void VisuGUI_ClippingDlg::ClickOnApply()
464 if (SVTK_ViewWindow* aViewWindow = VISU::GetViewWindow(myVisuGUI)) {
465 SUIT_OverrideCursor wc;
467 // Save clipping planes, currently applied to the presentation
468 // to enable restoring this state in case of failure.
469 // Refer to bugs IPAL8849, IPAL8850 for more information.
470 typedef vtkSmartPointer<vtkPlane> TPln;
471 typedef std::vector<TPln> TPlns;
472 bool isFailed = false;
474 int iopl = 0, nbOldPlanes = myPrs3d->GetNumberOfClippingPlanes();
475 for (; iopl < nbOldPlanes; iopl++) {
476 anOldPlanes.push_back(myPrs3d->GetClippingPlane(iopl));
479 // Try to apply new clipping
480 myPrs3d->RemoveAllClippingPlanes();
482 VISU::TPlanes::iterator anIter = myPlanes.begin();
483 for (; anIter != myPlanes.end(); anIter++) {
484 OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow);
485 anOrientedPlane->ShallowCopy(anIter->GetPointer());
486 if (!myPrs3d->AddClippingPlane(anOrientedPlane)) {
489 anOrientedPlane->Delete();
492 // Check contents of the resulting (clipped) presentation data
494 VISU_PipeLine* aPL = myPrs3d->GetPL();
495 VISU_PipeLine::TMapper* aM = aPL->GetMapper();
496 vtkDataSet* aPrsData = aM->GetInput();
498 if (aPrsData->GetNumberOfCells() < 1) {
504 // Restore previous clipping state because of failure.
505 myPrs3d->RemoveAllClippingPlanes();
507 TPlns::iterator anOldIter = anOldPlanes.begin();
508 for (; anOldIter != anOldPlanes.end(); anOldIter++) {
509 myPrs3d->AddClippingPlane(anOldIter->GetPointer());
512 SUIT_MessageBox::warn1(VISU::GetDesktop(myVisuGUI),
514 tr("WRN_EMPTY_RESULTING_PRS"),
518 //VISU::RenderViewWindow(aViewWindow);
519 VISU::RepaintViewWindows(myVisuGUI, myIO);
523 //=================================================================================
524 // function : ClickOnOk()
526 //=================================================================================
527 void VisuGUI_ClippingDlg::ClickOnOk()
533 //=================================================================================
534 // function : ClickOnCancel()
536 //=================================================================================
537 void VisuGUI_ClippingDlg::ClickOnCancel()
542 //=================================================================================
543 // function : onSelectionChanged()
544 // purpose : Called when selection is changed
545 //=================================================================================
546 void VisuGUI_ClippingDlg::onSelectionChanged()
548 if (SVTK_ViewWindow* aViewWindow = VISU::GetViewWindow(myVisuGUI)) {
549 Handle(SALOME_InteractiveObject) anIO;
550 CORBA::Object_var anObject = VISU::GetSelectedObj(myVisuGUI, &anIO);
552 if (CORBA::is_nil(anObject)) return;
553 PortableServer::ServantBase_var aServant = VISU::GetServant(anObject);
554 if (!aServant.in()) return;
556 myPrs3d = dynamic_cast<VISU::Prs3d_i*>(aServant.in());
558 std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
562 myPrs3d->GetOffset(anOffset);
564 vtkIdType anId = 0, anEnd = myPrs3d->GetNumberOfClippingPlanes();
565 for (; anId < anEnd; anId++) {
566 if (vtkImplicitFunction* aFunction = myPrs3d->GetClippingPlane(anId)) {
567 if (OrientedPlane* aPlane = OrientedPlane::SafeDownCast(aFunction)) {
568 OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow);
569 VISU::TVTKPlane aTVTKPlane(anOrientedPlane);
570 anOrientedPlane->Delete();
571 aTVTKPlane->ShallowCopy(aPlane);
572 aTVTKPlane->myActor->SetPosition(anOffset);
573 myPlanes.push_back(aTVTKPlane);
578 std::for_each(myPlanes.begin(),myPlanes.end(),
579 TSetVisiblity(PreviewCheckBox->isChecked()));
582 // enable/disable IJK tab
583 TabPane->setTabEnabled(WidgetIJKTab, isStructured());
585 VISU::RenderViewWindow(aViewWindow);
589 //=================================================================================
590 // function : onSelectPlane()
592 //=================================================================================
593 void VisuGUI_ClippingDlg::onSelectPlane(int theIndex)
595 if (!myPrs3d || myPlanes.empty())
598 OrientedPlane* aPlane = myPlanes[theIndex].GetPointer();
601 VISU::Orientation anOrientation = aPlane->GetOrientation();
604 double aRot[2] = {aPlane->myAngle[0], aPlane->myAngle[1]};
606 // Set plane parameters in the dialog
607 myIsSelectPlane = true;
608 setDistance(aPlane->GetDistance());
609 setRotation(aRot[0], aRot[1]);
611 switch (anOrientation) {
612 case VISU::XY: item = 0; break;
613 case VISU::YZ: item = 1; break;
614 case VISU::ZX: item = 2; break;
616 ComboBoxOrientation->setCurrentItem(item);
618 bool isIJK = (TabPane->currentPage() == WidgetIJKTab);
620 setIJKByNonStructured();
622 onSelectOrientation(item);
624 myIsSelectPlane = false;
627 //=================================================================================
628 // function : ClickOnNew()
630 //=================================================================================
631 void VisuGUI_ClippingDlg::ClickOnNew()
636 if (SVTK_ViewWindow* aViewWindow = VISU::GetViewWindow(myVisuGUI)) {
637 OrientedPlane* aPlane = OrientedPlane::New(aViewWindow);
638 VISU::TVTKPlane aTVTKPlane(aPlane);
639 myPlanes.push_back(aTVTKPlane);
642 myPrs3d->GetOffset(anOffset);
643 aTVTKPlane->myActor->SetPosition(anOffset);
645 if (PreviewCheckBox->isChecked())
646 aTVTKPlane->myActor->VisibilityOn();
649 SetCurrentPlaneParam();
653 //=================================================================================
654 // function : ClickOnDelete()
656 //=================================================================================
657 void VisuGUI_ClippingDlg::ClickOnDelete()
659 if (!myPrs3d || myPlanes.empty())
662 int aPlaneIndex = ComboBoxPlanes->currentItem();
664 VISU::TPlanes::iterator anIter = myPlanes.begin() + aPlaneIndex;
665 anIter->GetPointer()->myActor->SetVisibility(false);
666 myPlanes.erase(anIter);
668 if(AutoApplyCheckBox->isChecked())
672 if (SVTK_ViewWindow* aViewWindow = VISU::GetViewWindow(myVisuGUI))
673 VISU::RenderViewWindow(aViewWindow);
676 //=================================================================================
677 // function : onSelectOrientation()
679 //=================================================================================
680 void VisuGUI_ClippingDlg::onSelectOrientation(int theItem)
682 if (myPlanes.empty())
686 TextLabelRot1->setText(tr("LBL_ROTATION_YZ"));
687 TextLabelRot2->setText(tr("LBL_ROTATION_XZ"));
689 else if (theItem == 1) {
690 TextLabelRot1->setText(tr("LBL_ROTATION_ZX"));
691 TextLabelRot2->setText(tr("LBL_ROTATION_YX"));
693 else if (theItem == 2) {
694 TextLabelRot1->setText(tr("LBL_ROTATION_XY"));
695 TextLabelRot2->setText(tr("LBL_ROTATION_ZY"));
698 if((QComboBox*)sender() == ComboBoxOrientation)
699 SetCurrentPlaneParam();
702 //=================================================================================
703 // function : Sinchronize()
704 // purpose : update control values according to plane selection
705 //=================================================================================
706 void VisuGUI_ClippingDlg::Sinchronize()
708 int aNbPlanes = myPlanes.size();
709 ComboBoxPlanes->clear();
712 for (int i = 1; i<=aNbPlanes; i++) {
713 aName = QString(tr("PLANES_COMBO_ITEM_i")).arg(i);
714 ComboBoxPlanes->insertItem(aName);
717 int aPos = ComboBoxPlanes->count() - 1;
718 ComboBoxPlanes->setCurrentItem(aPos);
720 bool anIsControlsEnable = (aPos >= 0);
721 if (anIsControlsEnable) {
724 ComboBoxPlanes->insertItem(tr("PLANES_COMBO_ITEM_no"));
725 SpinBoxRot1->setValue(0.0);
726 SpinBoxRot2->setValue(0.0);
727 SpinBoxDistance->setValue(0.5);
730 buttonDelete ->setEnabled(anIsControlsEnable);
731 buttonApply ->setEnabled(anIsControlsEnable);
732 PreviewCheckBox ->setEnabled(anIsControlsEnable);
733 AutoApplyCheckBox ->setEnabled(anIsControlsEnable);
735 ComboBoxOrientation ->setEnabled(anIsControlsEnable);
736 SpinBoxDistance ->setEnabled(anIsControlsEnable);
737 SpinBoxRot1 ->setEnabled(anIsControlsEnable);
738 SpinBoxRot2 ->setEnabled(anIsControlsEnable);
740 ButtonGroupIJKAxis ->setEnabled(anIsControlsEnable);
741 SpinBoxIJKIndex ->setEnabled(anIsControlsEnable);
742 CheckBoxIJKPlaneReverse->setEnabled(anIsControlsEnable);
745 //=================================================================================
746 // function : setRotation()
748 //=================================================================================
749 void VisuGUI_ClippingDlg::setRotation(const double theRot1, const double theRot2)
751 SpinBoxRot1->setValue(theRot1);
752 SpinBoxRot2->setValue(theRot2);
755 //=================================================================================
756 // function : SetCurrentPlaneParam()
758 //=================================================================================
759 void VisuGUI_ClippingDlg::SetCurrentPlaneParam()
761 if (myPlanes.empty() || myIsSelectPlane)
764 int aCurPlaneIndex = ComboBoxPlanes->currentItem();
766 OrientedPlane* aPlane = myPlanes[aCurPlaneIndex].GetPointer();
769 VISU::Orientation anOrientation;
770 float aDir[3][3] = {{0, 0, 0}, {0, 0, 0}};
772 static double aCoeff = vtkMath::Pi()/180.0;
774 float aRot[2] = {getRotation1(), getRotation2()};
775 aPlane->myAngle[0] = aRot[0];
776 aPlane->myAngle[1] = aRot[1];
778 float anU[2] = {cos(aCoeff*aRot[0]), cos(aCoeff*aRot[1])};
779 float aV[2] = {sqrt(1.0-anU[0]*anU[0]), sqrt(1.0-anU[1]*anU[1])};
780 aV[0] = aRot[0] > 0? aV[0]: -aV[0];
781 aV[1] = aRot[1] > 0? aV[1]: -aV[1];
783 switch (ComboBoxOrientation->currentItem()) {
785 anOrientation = VISU::XY;
795 anOrientation = VISU::YZ;
805 anOrientation = VISU::ZX;
816 vtkMath::Cross(aDir[1],aDir[0],aNormal);
817 vtkMath::Normalize(aNormal);
818 vtkMath::Cross(aNormal,aDir[1],aDir[0]);
821 aPlane->SetOrientation(anOrientation);
822 aPlane->SetDistance(getDistance());
824 myPrs3d->SetPlaneParam(aNormal, 1. - getDistance(), aPlane);
826 vtkDataSet* aDataSet = myPrs3d->GetInput();
827 float *aPnt = aDataSet->GetCenter();
829 float* anOrigin = aPlane->GetOrigin();
830 float aDel = aDataSet->GetLength()/2.0;
832 float aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel},
833 {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}};
834 float aParam, aPnt0[3], aPnt1[3], aPnt2[3];
836 float aPnt01[3] = {aPnt[0] - aDelta[0][0] - aDelta[1][0],
837 aPnt[1] - aDelta[0][1] - aDelta[1][1],
838 aPnt[2] - aDelta[0][2] - aDelta[1][2]};
839 float aPnt02[3] = {aPnt01[0] + aNormal[0],
840 aPnt01[1] + aNormal[1],
841 aPnt01[2] + aNormal[2]};
842 vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0);
844 float aPnt11[3] = {aPnt[0] - aDelta[0][0] + aDelta[1][0],
845 aPnt[1] - aDelta[0][1] + aDelta[1][1],
846 aPnt[2] - aDelta[0][2] + aDelta[1][2]};
847 float aPnt12[3] = {aPnt11[0] + aNormal[0],
848 aPnt11[1] + aNormal[1],
849 aPnt11[2] + aNormal[2]};
850 vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1);
852 float aPnt21[3] = {aPnt[0] + aDelta[0][0] - aDelta[1][0],
853 aPnt[1] + aDelta[0][1] - aDelta[1][1],
854 aPnt[2] + aDelta[0][2] - aDelta[1][2]};
855 float aPnt22[3] = {aPnt21[0] + aNormal[0],
856 aPnt21[1] + aNormal[1],
857 aPnt21[2] + aNormal[2]};
858 vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2);
860 vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource;
861 aPlaneSource->SetNormal(aNormal[0],aNormal[1],aNormal[2]);
862 aPlaneSource->SetOrigin(aPnt0[0],aPnt0[1],aPnt0[2]);
863 aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]);
864 aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]);
866 if (AutoApplyCheckBox->isChecked())
869 if (SVTK_ViewWindow* vw = VISU::GetViewWindow(myVisuGUI))
870 VISU::RenderViewWindow(vw);
873 //=================================================================================
874 // function : onTabChanged
876 //=================================================================================
877 void VisuGUI_ClippingDlg::onTabChanged(QWidget* newTab)
879 if (newTab == WidgetIJKTab) // IJK
880 setIJKByNonStructured();
882 // set correct labels of rotation spin boxes
883 onSelectOrientation(ComboBoxOrientation->currentItem());
887 //=================================================================================
888 // function : SetCurrentPlaneIJKParam
889 // purpose : set non structured parameters by IJK parameters
890 //=================================================================================
891 void VisuGUI_ClippingDlg::SetCurrentPlaneIJKParam()
893 if (myPlanes.empty() || myIsSelectPlane || !WidgetIJKTab->isEnabled())
896 VISU::Result_i* result = myPrs3d ? myPrs3d->GetResult() : 0;
901 int i, axId = ButtonGroupIJKAxis->id (ButtonGroupIJKAxis->selected());
902 VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) axId;
904 const vector<float> * values =
905 result->GetAxisInfo(myPrs3d->GetMeshName(), axis, dir);
910 int index = SpinBoxIJKIndex->value();
912 if (index < values->size())
913 distance = (*values)[ index ];
915 // find id of axis closest to dir
919 double cos[3] = { gp::DZ() * dir, gp::DX() * dir, gp::DY() * dir };
921 for (i = 0; i < 3; ++i) {
922 if (Abs(cos[ i ]) > Abs (maxCos)) {
927 // find rotation angles
930 (axId == 0) ? 2 : axId - 1,
931 (axId == 2) ? 0 : axId + 1
933 static double aCoeff = 180.0/vtkMath::Pi();
934 for (i = 0; i < 2; ++i) {
935 float cosin = cos[ rotId[ i ]];
938 angle[ i ] = asin(cosin) * aCoeff;
940 angle[ i ] += 180. * (angle[ i ] < 0 ? 1. : -1.);
942 if (CheckBoxIJKPlaneReverse->isChecked()) {
943 angle[ 0 ] += 180. * (angle[ 0 ] < 0 ? 1. : -1.);
944 distance = 1. - distance;
947 distance = 1. - distance;
950 myIsSelectPlane = true;
951 ComboBoxOrientation->setCurrentItem(axId);
952 setRotation(-angle[0], -angle[1]);
953 setDistance(distance);
954 myIsSelectPlane = false;
956 SetCurrentPlaneParam();
959 //=================================================================================
960 // function : setIJKByNonStructured
961 // purpose : convert current non structured parameters to structured ones
962 //=================================================================================
963 void VisuGUI_ClippingDlg::setIJKByNonStructured()
965 if (!myPrs3d || myPlanes.empty() || !myPrs3d->GetResult())
969 int planeIndex = ComboBoxPlanes->currentItem();
970 OrientedPlane* plane = myPlanes[ planeIndex ].GetPointer();
971 vtkPlaneSource* planeSource = plane->myPlaneSource;
972 float * planeNormal = planeSource->GetNormal();
973 gp_Dir normal(planeNormal[0], planeNormal[1], planeNormal[2]);
975 // find a grid axis most co-directed with plane normal
976 // and cartesian axis most co-directed with plane normal
977 int i, maxAx = 0, gridAxId = 0;
980 const vector<float> *curValues, *values = 0;
981 VISU::Result_i* result = myPrs3d->GetResult();
982 for (i = 0; i < 3; ++i) {
983 VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) i;
984 curValues = result->GetAxisInfo(myPrs3d->GetMeshName(), axis, dir);
986 double dot = normal * dir;
987 if (Abs(dot) > Abs(maxDot)) {
994 if (Abs (planeNormal[ maxAx ]) < Abs (planeNormal[ i ]))
998 axDir.SetCoord(maxAx + 1, 1.);
1001 double v = SpinBoxDistance->value();
1003 bool reverse = (normal * axDir < 0); // normal and axis are opposite
1004 if (gridDir * axDir < 0) // grid dir and axis are opposite
1008 for (i = 0; i < values->size(); ++i)
1009 if ((*values)[ i ] > v)
1011 if (i == values->size())
1013 if (i != 0 && (*values)[ i ] - v > v - (*values)[ i - 1])
1016 // set control values
1017 myIsSelectPlane = true;
1018 CheckBoxIJKPlaneReverse->setChecked(normal * axDir < 0);
1019 SpinBoxIJKIndex->setValue(i);
1020 ButtonGroupIJKAxis->setButton(gridAxId);
1021 onIJKAxisChanged(gridAxId); // update label and range of index
1022 myIsSelectPlane = false;
1024 SetCurrentPlaneIJKParam();
1027 //=================================================================================
1028 // function : isStructured
1029 // purpose : return true if mesh is structured
1030 //=================================================================================
1031 bool VisuGUI_ClippingDlg::isStructured() const
1033 VISU::Result_i* result = myPrs3d ? myPrs3d->GetResult() : 0;
1036 return result->GetAxisInfo(myPrs3d->GetMeshName(),
1037 VISU::Result_i::AXIS_X,
1043 //=================================================================================
1044 // function : onIJKAxisChanged
1045 // purpose : update Index range and call SetCurrentPlaneParam()
1046 //=================================================================================
1047 void VisuGUI_ClippingDlg::onIJKAxisChanged(int axisId)
1051 VISU::Result_i* result = myPrs3d ? myPrs3d->GetResult() : 0;
1053 VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) axisId;
1055 const vector<float> * indices = result->GetAxisInfo(myPrs3d->GetMeshName(),
1058 maxIndex = indices->size() - 1;
1060 QString text = tr("LBL_IJK_INDEX_TO_arg").arg(maxIndex);
1061 TextLabelIJKIndex->setText(text);
1062 SpinBoxIJKIndex->setRange(0, maxIndex);
1064 if (SpinBoxIJKIndex->value() > maxIndex)
1065 SpinBoxIJKIndex->setValue(0);
1067 SetCurrentPlaneIJKParam();
1070 //=================================================================================
1071 // function : OnPreviewToggle()
1073 //=================================================================================
1074 void VisuGUI_ClippingDlg::OnPreviewToggle (bool theIsToggled)
1076 std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(theIsToggled));
1077 if (SVTK_ViewWindow* vw = VISU::GetViewWindow(myVisuGUI))
1078 VISU::RenderViewWindow(vw);