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/
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"
34 #include "SVTK_ViewWindow.h"
36 #include "SUIT_Session.h"
37 #include "SUIT_Desktop.h"
38 #include "SUIT_MessageBox.h"
39 #include "SUIT_ResourceMgr.h"
40 #include "SUIT_OverrideCursor.h"
42 #include "SALOME_Actor.h"
46 #include <qpushbutton.h>
47 #include <qcombobox.h>
48 #include <qcheckbox.h>
50 #include <qgroupbox.h>
51 #include <qvalidator.h>
52 #include <qtabwidget.h>
53 #include <qhbuttongroup.h>
54 #include <qradiobutton.h>
59 #include <vtkCamera.h>
60 #include <vtkRenderer.h>
61 #include <vtkDataSet.h>
62 #include <vtkDataSetMapper.h>
63 #include <vtkImplicitFunction.h>
64 #include <vtkPlaneSource.h>
65 #include <vtkPolyData.h>
66 #include <vtkUnstructuredGrid.h>
67 #include <vtkProperty.h>
75 float GetFloat (const QString& theValue, float theDefault)
77 if (theValue.isEmpty()) return theDefault;
78 SUIT_ResourceMgr* aResourceMgr = VISU::GetResourceMgr();
79 QString aValue = aResourceMgr->stringValue("VISU",theValue);
80 if (aValue.isEmpty()) return theDefault;
81 return aValue.toFloat();
84 void RenderViewWindow (SVTK_ViewWindow* vw)
87 vw->getRenderer()->ResetCameraClippingRange();
92 void RangeStepAndValidator (QtxDblSpinBox* theSpinBox, double min, double max,
93 double step, unsigned short decimals)
95 theSpinBox->setRange(min, max);
96 theSpinBox->setLineStep(step);
97 ((QDoubleValidator*)theSpinBox->validator())->setRange(min, max, decimals);
101 //=================================================================================
102 //class : OrientedPlane
104 //=================================================================================
105 class OrientedPlane: public vtkPlane
107 SVTK_ViewWindow* myViewWindow;
109 vtkDataSetMapper* myMapper;
112 static OrientedPlane * New() {
113 return new OrientedPlane();
115 static OrientedPlane * New (SVTK_ViewWindow* vw) {
116 return new OrientedPlane(vw);
118 vtkTypeMacro(OrientedPlane, vtkPlane);
121 VISU::Orientation myOrientation;
125 vtkPlaneSource* myPlaneSource;
126 SALOME_Actor *myActor;
128 void SetOrientation(VISU::Orientation theOrientation) {myOrientation = theOrientation;}
129 VISU::Orientation GetOrientation() {return myOrientation;}
131 void SetDistance(float theDistance) {myDistance = theDistance;}
132 float GetDistance() {return myDistance;}
134 void ShallowCopy(OrientedPlane* theOrientedPlane){
135 SetNormal(theOrientedPlane->GetNormal());
136 SetOrigin(theOrientedPlane->GetOrigin());
138 myOrientation = theOrientedPlane->GetOrientation();
139 myDistance = theOrientedPlane->GetDistance();
141 myAngle[0] = theOrientedPlane->myAngle[0];
142 myAngle[1] = theOrientedPlane->myAngle[1];
144 myPlaneSource->SetNormal(theOrientedPlane->myPlaneSource->GetNormal());
145 myPlaneSource->SetOrigin(theOrientedPlane->myPlaneSource->GetOrigin());
146 myPlaneSource->SetPoint1(theOrientedPlane->myPlaneSource->GetPoint1());
147 myPlaneSource->SetPoint2(theOrientedPlane->myPlaneSource->GetPoint2());
151 OrientedPlane(SVTK_ViewWindow* vw):
152 myOrientation(VISU::XY),
157 myViewWindow->AddActor(myActor);
161 myOrientation(VISU::XY),
169 myPlaneSource = vtkPlaneSource::New();
171 myAngle[0] = myAngle[1] = 0.0;
173 // Create and display actor
174 myMapper = vtkDataSetMapper::New();
175 myMapper->SetInput(myPlaneSource->GetOutput());
177 myActor = SALOME_Actor::New();
178 myActor->VisibilityOff();
179 myActor->PickableOff();
180 myActor->SetInfinitive(true);
181 myActor->SetMapper(myMapper);
183 vtkProperty* aProp = vtkProperty::New();
186 SUIT_ResourceMgr* aResourceMgr = VISU::GetResourceMgr();
188 QColor aFillColor = aResourceMgr->colorValue("SMESH", "fill_color", QColor(0, 170, 255));
189 anRGB[0] = aFillColor.red()/255.;
190 anRGB[1] = aFillColor.green()/255.;
191 anRGB[2] = aFillColor.blue()/255.;
192 aProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
193 aProp->SetOpacity(0.75);
194 myActor->SetProperty(aProp);
197 vtkProperty* aBackProp = vtkProperty::New();
198 QColor aBackFaceColor = aResourceMgr->colorValue("SMESH", "backface_color", QColor(0, 0, 255));//@
199 anRGB[0] = aBackFaceColor.red()/255.;
200 anRGB[1] = aBackFaceColor.green()/255.;
201 anRGB[2] = aBackFaceColor.blue()/255.;
202 aBackProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
203 aBackProp->SetOpacity(0.75);
204 myActor->SetBackfaceProperty(aBackProp);
211 myViewWindow->RemoveActor(myActor);
215 myMapper->RemoveAllInputs();
218 myPlaneSource->UnRegisterAllOutputs();
219 myPlaneSource->Delete();
224 OrientedPlane(const OrientedPlane&);
225 void operator=(const OrientedPlane&);
228 struct TSetVisiblity {
229 TSetVisiblity(int theIsVisible): myIsVisible(theIsVisible){}
230 void operator()(VISU::TVTKPlane& theOrientedPlane){
231 theOrientedPlane->myActor->SetVisibility(myIsVisible);
236 //=================================================================================
237 // class : VisuGUI_ClippingDlg()
240 //=================================================================================
241 VisuGUI_ClippingDlg::VisuGUI_ClippingDlg (VisuGUI* theModule,
245 : QDialog(VISU::GetDesktop(theModule), name, modal, WStyle_Customize |
246 WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
247 mySelectionMgr(VISU::GetSelectionMgr(theModule)),
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 buttonCancel = new QPushButton (GroupButtons, "buttonCancel");
324 buttonCancel->setText(tr("BUT_CLOSE"));
325 buttonCancel->setAutoDefault(TRUE);
326 GroupButtonsLayout->addWidget(buttonCancel, 0, 3);
327 buttonApply = new QPushButton (GroupButtons, "buttonApply");
328 buttonApply->setText(tr("BUT_APPLY"));
329 buttonApply->setAutoDefault(TRUE);
330 GroupButtonsLayout->addWidget(buttonApply, 0, 1);
331 QSpacerItem* spacer_9 = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
332 GroupButtonsLayout->addItem(spacer_9, 0, 2);
333 buttonOk = new QPushButton (GroupButtons, "buttonOk");
334 buttonOk->setText(tr("BUT_OK"));
335 buttonOk->setAutoDefault(TRUE);
336 buttonOk->setDefault(TRUE);
337 GroupButtonsLayout->addWidget(buttonOk, 0, 0);
339 VisuGUI_ClippingDlgLayout->addMultiCellWidget(GroupPlanes, 0, 0, 0, 1);
340 VisuGUI_ClippingDlgLayout->addMultiCellWidget(GroupParameters, 1, 1, 0, 1);
341 VisuGUI_ClippingDlgLayout->addWidget(PreviewCheckBox, 2, 0);
342 VisuGUI_ClippingDlgLayout->addWidget(AutoApplyCheckBox, 2, 1);
343 VisuGUI_ClippingDlgLayout->addMultiCellWidget(GroupButtons, 3, 3, 0, 1);
346 VISU::RangeStepAndValidator(SpinBoxDistance, 0.0, 1.0, 0.01, 3);
347 VISU::RangeStepAndValidator(SpinBoxRot1, -180.0, 180.0, 1, 3);
348 VISU::RangeStepAndValidator(SpinBoxRot2, -180.0, 180.0, 1, 3);
350 ComboBoxOrientation->insertItem(tr("PARALLEL_XOY_COMBO_ITEM"));
351 ComboBoxOrientation->insertItem(tr("PARALLEL_YOZ_COMBO_ITEM"));
352 ComboBoxOrientation->insertItem(tr("PARALLEL_ZOX_COMBO_ITEM"));
354 SpinBoxDistance->setValue(0.5);
357 myIsSelectPlane = false;
358 onSelectionChanged();
360 // signals and slots connections :
361 connect(ComboBoxPlanes , SIGNAL(activated(int)) , this, SLOT(onSelectPlane(int)));
362 connect(buttonNew , SIGNAL(clicked()) , this, SLOT(ClickOnNew()));
363 connect(buttonDelete , SIGNAL(clicked()) , this, SLOT(ClickOnDelete()));
364 connect(ComboBoxOrientation , SIGNAL(activated(int)) , this, SLOT(onSelectOrientation(int)));
365 connect(SpinBoxDistance , SIGNAL(valueChanged(double)) , this, SLOT(SetCurrentPlaneParam()));
366 connect(SpinBoxRot1 , SIGNAL(valueChanged(double)) , this, SLOT(SetCurrentPlaneParam()));
367 connect(SpinBoxRot2 , SIGNAL(valueChanged(double)) , this, SLOT(SetCurrentPlaneParam()));
368 connect(ButtonGroupIJKAxis , SIGNAL(clicked(int)) , this, SLOT(onIJKAxisChanged(int)));
369 connect(SpinBoxIJKIndex , SIGNAL(valueChanged(int)) , this, SLOT(SetCurrentPlaneIJKParam()));
370 connect(CheckBoxIJKPlaneReverse, SIGNAL(toggled(bool)) , this, SLOT(SetCurrentPlaneIJKParam()));
371 connect(TabPane , SIGNAL(currentChanged (QWidget*)), this, SLOT(onTabChanged(QWidget*)));
373 connect(PreviewCheckBox , SIGNAL(toggled(bool)), this, SLOT(OnPreviewToggle(bool)));
374 connect(AutoApplyCheckBox, SIGNAL(toggled(bool)), this, SLOT(ClickOnApply()));
376 connect(buttonOk , SIGNAL(clicked()), this, SLOT(ClickOnOk()));
377 connect(buttonApply , SIGNAL(clicked()), this, SLOT(ClickOnApply()));
378 connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()));
380 connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionChanged()));
385 //=================================================================================
386 // function : ~VisuGUI_ClippingDlg()
388 //=================================================================================
389 VisuGUI_ClippingDlg::~VisuGUI_ClippingDlg()
391 // no need to delete child widgets, Qt does it all for us
392 std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
393 VISU::RenderViewWindow(VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI));
396 //=================================================================================
397 // function : createParamsTab
399 //=================================================================================
400 QWidget* VisuGUI_ClippingDlg::createParamsTab()
402 QFrame* GroupParameters = new QFrame(this);
403 QGridLayout* GroupParametersLayout = new QGridLayout(GroupParameters);
404 GroupParametersLayout->setAlignment(Qt::AlignTop);
405 GroupParametersLayout->setSpacing(6);
406 GroupParametersLayout->setMargin(11);
408 TextLabelOrientation = new QLabel(GroupParameters, "TextLabelOrientation");
409 TextLabelOrientation->setText(tr("LBL_ORIENTATION"));
410 GroupParametersLayout->addWidget(TextLabelOrientation, 0, 0);
412 ComboBoxOrientation = new QComboBox(GroupParameters, "ComboBoxOrientation");
413 GroupParametersLayout->addWidget(ComboBoxOrientation, 0, 1);
415 TextLabelDistance = new QLabel(GroupParameters, "TextLabelDistance");
416 TextLabelDistance->setText(tr("LBL_DISTANCE"));
417 GroupParametersLayout->addWidget(TextLabelDistance, 1, 0);
419 SpinBoxDistance = new QtxDblSpinBox(GroupParameters, "SpinBoxDistance");
420 GroupParametersLayout->addWidget(SpinBoxDistance, 1, 1);
422 TextLabelRot1 = new QLabel(GroupParameters, "TextLabelRot1");
423 TextLabelRot1->setText(tr("LBL_ROTATION_YZ"));
424 GroupParametersLayout->addWidget(TextLabelRot1, 2, 0);
426 SpinBoxRot1 = new QtxDblSpinBox(GroupParameters, "SpinBoxRot1");
427 GroupParametersLayout->addWidget(SpinBoxRot1, 2, 1);
429 TextLabelRot2 = new QLabel(GroupParameters, "TextLabelRot2");
430 TextLabelRot2->setText(tr("LBL_ROTATION_XZ"));
431 GroupParametersLayout->addWidget(TextLabelRot2, 3, 0);
433 SpinBoxRot2 = new QtxDblSpinBox(GroupParameters, "SpinBoxRot2");
434 GroupParametersLayout->addWidget(SpinBoxRot2, 3, 1);
436 return GroupParameters;
439 //=================================================================================
440 // function : createIJKParamsTab
442 //=================================================================================
443 QWidget* VisuGUI_ClippingDlg::createIJKParamsTab()
446 WidgetIJKTab = new QFrame(this);
447 QGridLayout* IJKParametersLayout = new QGridLayout(WidgetIJKTab);
448 IJKParametersLayout->setAlignment(Qt::AlignTop);
449 IJKParametersLayout->setSpacing(6);
450 IJKParametersLayout->setMargin(11);
453 ButtonGroupIJKAxis = new QHButtonGroup (tr("GRP_IJK_AXIS"), WidgetIJKTab);
454 new QRadioButton (tr("I_RADIO_BTN"), ButtonGroupIJKAxis); // 0
455 new QRadioButton (tr("J_RADIO_BTN"), ButtonGroupIJKAxis); // 1
456 new QRadioButton (tr("K_RADIO_BTN"), ButtonGroupIJKAxis); // 2
457 ButtonGroupIJKAxis->setButton(0);
460 TextLabelIJKIndex = new QLabel(WidgetIJKTab, "TextLabelIJKIndex");
461 TextLabelIJKIndex->setText(tr("LBL_IJK_INDEX"));
462 SpinBoxIJKIndex = new QSpinBox(WidgetIJKTab, "SpinBoxIJKIndex");
465 CheckBoxIJKPlaneReverse = new QCheckBox (tr("REVERSE_NORMAL_CHK"), WidgetIJKTab);
466 CheckBoxIJKPlaneReverse->setChecked(false);
468 IJKParametersLayout->addMultiCellWidget(ButtonGroupIJKAxis, 0, 0, 0, 1);
469 IJKParametersLayout->addWidget(TextLabelIJKIndex, 1, 0);
470 IJKParametersLayout->addWidget(SpinBoxIJKIndex, 1, 1);
471 IJKParametersLayout->addWidget(CheckBoxIJKPlaneReverse, 2, 0);
476 //=================================================================================
477 // function : ClickOnApply()
479 //=================================================================================
480 void VisuGUI_ClippingDlg::ClickOnApply()
485 if (SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI)) {
486 SUIT_OverrideCursor wc;
488 QWidget *aCurrWid = this->focusWidget();
489 aCurrWid->clearFocus();
490 aCurrWid->setFocus();
492 // Save clipping planes, currently applied to the presentation
493 // to enable restoring this state in case of failure.
494 // Refer to bugs IPAL8849, IPAL8850 for more information.
495 typedef vtkSmartPointer<vtkPlane> TPln;
496 typedef std::vector<TPln> TPlns;
497 bool isFailed = false;
499 int iopl = 0, nbOldPlanes = myPrs3d->GetNumberOfClippingPlanes();
500 for (; iopl < nbOldPlanes; iopl++) {
501 anOldPlanes.push_back(myPrs3d->GetClippingPlane(iopl));
504 // Try to apply new clipping
505 myPrs3d->RemoveAllClippingPlanes();
507 VISU::TPlanes::iterator anIter = myPlanes.begin();
508 for (; anIter != myPlanes.end(); anIter++) {
509 OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow);
510 anOrientedPlane->ShallowCopy(anIter->GetPointer());
511 if (!myPrs3d->AddClippingPlane(anOrientedPlane)) {
514 anOrientedPlane->Delete();
517 // Check contents of the resulting (clipped) presentation data
519 VISU_PipeLine* aPL = myPrs3d->GetPL();
520 VISU_PipeLine::TMapper* aM = aPL->GetMapper();
521 vtkDataSet* aPrsData = aM->GetInput();
523 if (aPrsData->GetNumberOfCells() < 1) {
529 // Restore previous clipping state because of failure.
530 myPrs3d->RemoveAllClippingPlanes();
532 TPlns::iterator anOldIter = anOldPlanes.begin();
533 for (; anOldIter != anOldPlanes.end(); anOldIter++) {
534 myPrs3d->AddClippingPlane(anOldIter->GetPointer());
537 SUIT_MessageBox::warn1(VISU::GetDesktop(myVisuGUI),
539 tr("WRN_EMPTY_RESULTING_PRS"),
543 //VISU::RenderViewWindow(aViewWindow);
544 VISU::RepaintViewWindows(myVisuGUI, myIO);
548 //=================================================================================
549 // function : ClickOnOk()
551 //=================================================================================
552 void VisuGUI_ClippingDlg::ClickOnOk()
558 //=================================================================================
559 // function : ClickOnCancel()
561 //=================================================================================
562 void VisuGUI_ClippingDlg::ClickOnCancel()
567 //=================================================================================
568 // function : onSelectionChanged()
569 // purpose : Called when selection is changed
570 //=================================================================================
571 void VisuGUI_ClippingDlg::onSelectionChanged()
573 if (SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI)) {
574 Handle(SALOME_InteractiveObject) anIO;
575 CORBA::Object_var anObject = VISU::GetSelectedObj(myVisuGUI, &anIO);
577 if (CORBA::is_nil(anObject)) return;
578 PortableServer::ServantBase_var aServant = VISU::GetServant(anObject);
579 if (!aServant.in()) return;
581 myPrs3d = dynamic_cast<VISU::Prs3d_i*>(aServant.in());
583 std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
587 myPrs3d->GetOffset(anOffset);
589 vtkIdType anId = 0, anEnd = myPrs3d->GetNumberOfClippingPlanes();
590 for (; anId < anEnd; anId++) {
591 if (vtkImplicitFunction* aFunction = myPrs3d->GetClippingPlane(anId)) {
592 if (OrientedPlane* aPlane = OrientedPlane::SafeDownCast(aFunction)) {
593 OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow);
594 VISU::TVTKPlane aTVTKPlane(anOrientedPlane);
595 anOrientedPlane->Delete();
596 aTVTKPlane->ShallowCopy(aPlane);
597 aTVTKPlane->myActor->SetPosition(anOffset);
598 myPlanes.push_back(aTVTKPlane);
603 std::for_each(myPlanes.begin(),myPlanes.end(),
604 TSetVisiblity(PreviewCheckBox->isChecked()));
607 // enable/disable IJK tab
608 TabPane->setTabEnabled(WidgetIJKTab, isStructured());
610 VISU::RenderViewWindow(aViewWindow);
614 //=================================================================================
615 // function : onSelectPlane()
617 //=================================================================================
618 void VisuGUI_ClippingDlg::onSelectPlane(int theIndex)
620 if (!myPrs3d || myPlanes.empty())
623 OrientedPlane* aPlane = myPlanes[theIndex].GetPointer();
626 VISU::Orientation anOrientation = aPlane->GetOrientation();
629 double aRot[2] = {aPlane->myAngle[0], aPlane->myAngle[1]};
631 // Set plane parameters in the dialog
632 myIsSelectPlane = true;
633 setDistance(aPlane->GetDistance());
634 setRotation(aRot[0], aRot[1]);
636 switch (anOrientation) {
637 case VISU::XY: item = 0; break;
638 case VISU::YZ: item = 1; break;
639 case VISU::ZX: item = 2; break;
641 ComboBoxOrientation->setCurrentItem(item);
643 bool isIJK = (TabPane->currentPage() == WidgetIJKTab);
645 setIJKByNonStructured();
647 onSelectOrientation(item);
649 myIsSelectPlane = false;
652 //=================================================================================
653 // function : ClickOnNew()
655 //=================================================================================
656 void VisuGUI_ClippingDlg::ClickOnNew()
661 if (SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI)) {
662 OrientedPlane* aPlane = OrientedPlane::New(aViewWindow);
663 VISU::TVTKPlane aTVTKPlane(aPlane);
664 myPlanes.push_back(aTVTKPlane);
667 myPrs3d->GetOffset(anOffset);
668 aTVTKPlane->myActor->SetPosition(anOffset);
670 if (PreviewCheckBox->isChecked())
671 aTVTKPlane->myActor->VisibilityOn();
674 SetCurrentPlaneParam();
678 //=================================================================================
679 // function : ClickOnDelete()
681 //=================================================================================
682 void VisuGUI_ClippingDlg::ClickOnDelete()
684 if (!myPrs3d || myPlanes.empty())
687 int aPlaneIndex = ComboBoxPlanes->currentItem();
689 VISU::TPlanes::iterator anIter = myPlanes.begin() + aPlaneIndex;
690 anIter->GetPointer()->myActor->SetVisibility(false);
691 myPlanes.erase(anIter);
693 if(AutoApplyCheckBox->isChecked())
697 if (SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI))
698 VISU::RenderViewWindow(aViewWindow);
701 //=================================================================================
702 // function : onSelectOrientation()
704 //=================================================================================
705 void VisuGUI_ClippingDlg::onSelectOrientation(int theItem)
707 if (myPlanes.empty())
711 TextLabelRot1->setText(tr("LBL_ROTATION_YZ"));
712 TextLabelRot2->setText(tr("LBL_ROTATION_XZ"));
714 else if (theItem == 1) {
715 TextLabelRot1->setText(tr("LBL_ROTATION_ZX"));
716 TextLabelRot2->setText(tr("LBL_ROTATION_YX"));
718 else if (theItem == 2) {
719 TextLabelRot1->setText(tr("LBL_ROTATION_XY"));
720 TextLabelRot2->setText(tr("LBL_ROTATION_ZY"));
723 if((QComboBox*)sender() == ComboBoxOrientation)
724 SetCurrentPlaneParam();
727 //=================================================================================
728 // function : Sinchronize()
729 // purpose : update control values according to plane selection
730 //=================================================================================
731 void VisuGUI_ClippingDlg::Sinchronize()
733 int aNbPlanes = myPlanes.size();
734 ComboBoxPlanes->clear();
737 for (int i = 1; i<=aNbPlanes; i++) {
738 aName = QString(tr("PLANES_COMBO_ITEM_i")).arg(i);
739 ComboBoxPlanes->insertItem(aName);
742 int aPos = ComboBoxPlanes->count() - 1;
743 ComboBoxPlanes->setCurrentItem(aPos);
745 bool anIsControlsEnable = (aPos >= 0);
746 if (anIsControlsEnable) {
749 ComboBoxPlanes->insertItem(tr("PLANES_COMBO_ITEM_no"));
750 SpinBoxRot1->setValue(0.0);
751 SpinBoxRot2->setValue(0.0);
752 SpinBoxDistance->setValue(0.5);
755 buttonDelete ->setEnabled(anIsControlsEnable);
756 buttonApply ->setEnabled(anIsControlsEnable);
757 PreviewCheckBox ->setEnabled(anIsControlsEnable);
758 AutoApplyCheckBox ->setEnabled(anIsControlsEnable);
760 ComboBoxOrientation ->setEnabled(anIsControlsEnable);
761 SpinBoxDistance ->setEnabled(anIsControlsEnable);
762 SpinBoxRot1 ->setEnabled(anIsControlsEnable);
763 SpinBoxRot2 ->setEnabled(anIsControlsEnable);
765 ButtonGroupIJKAxis ->setEnabled(anIsControlsEnable);
766 SpinBoxIJKIndex ->setEnabled(anIsControlsEnable);
767 CheckBoxIJKPlaneReverse->setEnabled(anIsControlsEnable);
770 //=================================================================================
771 // function : setRotation()
773 //=================================================================================
774 void VisuGUI_ClippingDlg::setRotation(const double theRot1, const double theRot2)
776 SpinBoxRot1->setValue(theRot1);
777 SpinBoxRot2->setValue(theRot2);
780 //=================================================================================
781 // function : SetCurrentPlaneParam()
783 //=================================================================================
784 void VisuGUI_ClippingDlg::SetCurrentPlaneParam()
786 if (myPlanes.empty() || myIsSelectPlane)
789 int aCurPlaneIndex = ComboBoxPlanes->currentItem();
791 OrientedPlane* aPlane = myPlanes[aCurPlaneIndex].GetPointer();
794 VISU::Orientation anOrientation;
795 float aDir[3][3] = {{0, 0, 0}, {0, 0, 0}};
797 static double aCoeff = vtkMath::Pi()/180.0;
799 float aRot[2] = {getRotation1(), getRotation2()};
800 aPlane->myAngle[0] = aRot[0];
801 aPlane->myAngle[1] = aRot[1];
803 float anU[2] = {cos(aCoeff*aRot[0]), cos(aCoeff*aRot[1])};
804 float aV[2] = {sqrt(1.0-anU[0]*anU[0]), sqrt(1.0-anU[1]*anU[1])};
805 aV[0] = aRot[0] > 0? aV[0]: -aV[0];
806 aV[1] = aRot[1] > 0? aV[1]: -aV[1];
808 switch (ComboBoxOrientation->currentItem()) {
810 anOrientation = VISU::XY;
820 anOrientation = VISU::YZ;
830 anOrientation = VISU::ZX;
841 vtkMath::Cross(aDir[1],aDir[0],aNormal);
842 vtkMath::Normalize(aNormal);
843 vtkMath::Cross(aNormal,aDir[1],aDir[0]);
846 aPlane->SetOrientation(anOrientation);
847 aPlane->SetDistance(getDistance());
849 myPrs3d->SetPlaneParam(aNormal, 1. - getDistance(), aPlane);
851 vtkDataSet* aDataSet = myPrs3d->GetInput();
852 float *aPnt = aDataSet->GetCenter();
854 float* anOrigin = aPlane->GetOrigin();
855 float aDel = aDataSet->GetLength()/2.0;
857 float aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel},
858 {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}};
859 float aParam, aPnt0[3], aPnt1[3], aPnt2[3];
861 float aPnt01[3] = {aPnt[0] - aDelta[0][0] - aDelta[1][0],
862 aPnt[1] - aDelta[0][1] - aDelta[1][1],
863 aPnt[2] - aDelta[0][2] - aDelta[1][2]};
864 float aPnt02[3] = {aPnt01[0] + aNormal[0],
865 aPnt01[1] + aNormal[1],
866 aPnt01[2] + aNormal[2]};
867 vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0);
869 float aPnt11[3] = {aPnt[0] - aDelta[0][0] + aDelta[1][0],
870 aPnt[1] - aDelta[0][1] + aDelta[1][1],
871 aPnt[2] - aDelta[0][2] + aDelta[1][2]};
872 float aPnt12[3] = {aPnt11[0] + aNormal[0],
873 aPnt11[1] + aNormal[1],
874 aPnt11[2] + aNormal[2]};
875 vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1);
877 float aPnt21[3] = {aPnt[0] + aDelta[0][0] - aDelta[1][0],
878 aPnt[1] + aDelta[0][1] - aDelta[1][1],
879 aPnt[2] + aDelta[0][2] - aDelta[1][2]};
880 float aPnt22[3] = {aPnt21[0] + aNormal[0],
881 aPnt21[1] + aNormal[1],
882 aPnt21[2] + aNormal[2]};
883 vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2);
885 vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource;
886 aPlaneSource->SetNormal(aNormal[0],aNormal[1],aNormal[2]);
887 aPlaneSource->SetOrigin(aPnt0[0],aPnt0[1],aPnt0[2]);
888 aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]);
889 aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]);
891 if (AutoApplyCheckBox->isChecked())
894 if (SVTK_ViewWindow* vw = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI))
895 VISU::RenderViewWindow(vw);
898 //=================================================================================
899 // function : onTabChanged
901 //=================================================================================
902 void VisuGUI_ClippingDlg::onTabChanged(QWidget* newTab)
904 if (newTab == WidgetIJKTab) // IJK
905 setIJKByNonStructured();
907 // set correct labels of rotation spin boxes
908 onSelectOrientation(ComboBoxOrientation->currentItem());
912 //=================================================================================
913 // function : SetCurrentPlaneIJKParam
914 // purpose : set non structured parameters by IJK parameters
915 //=================================================================================
916 void VisuGUI_ClippingDlg::SetCurrentPlaneIJKParam()
918 if (myPlanes.empty() || myIsSelectPlane || !WidgetIJKTab->isEnabled())
921 VISU::Result_i* result = myPrs3d ? myPrs3d->GetResult() : 0;
926 int i, axId = ButtonGroupIJKAxis->id (ButtonGroupIJKAxis->selected());
927 VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) axId;
929 const vector<float> * values =
930 result->GetAxisInfo(myPrs3d->GetMeshName(), axis, dir);
935 int index = SpinBoxIJKIndex->value();
937 if (index < values->size())
938 distance = (*values)[ index ];
940 // find id of axis closest to dir
944 double cos[3] = { gp::DZ() * dir, gp::DX() * dir, gp::DY() * dir };
946 for (i = 0; i < 3; ++i) {
947 if (Abs(cos[ i ]) > Abs (maxCos)) {
952 // find rotation angles
955 (axId == 0) ? 2 : axId - 1,
956 (axId == 2) ? 0 : axId + 1
958 static double aCoeff = 180.0/vtkMath::Pi();
959 for (i = 0; i < 2; ++i) {
960 float cosin = cos[ rotId[ i ]];
963 angle[ i ] = asin(cosin) * aCoeff;
965 angle[ i ] += 180. * (angle[ i ] < 0 ? 1. : -1.);
967 if (CheckBoxIJKPlaneReverse->isChecked()) {
968 angle[ 0 ] += 180. * (angle[ 0 ] < 0 ? 1. : -1.);
969 distance = 1. - distance;
972 distance = 1. - distance;
975 myIsSelectPlane = true;
976 ComboBoxOrientation->setCurrentItem(axId);
977 setRotation(-angle[0], -angle[1]);
978 setDistance(distance);
979 myIsSelectPlane = false;
981 SetCurrentPlaneParam();
984 //=================================================================================
985 // function : setIJKByNonStructured
986 // purpose : convert current non structured parameters to structured ones
987 //=================================================================================
988 void VisuGUI_ClippingDlg::setIJKByNonStructured()
990 if (!myPrs3d || myPlanes.empty() || !myPrs3d->GetResult())
994 int planeIndex = ComboBoxPlanes->currentItem();
995 OrientedPlane* plane = myPlanes[ planeIndex ].GetPointer();
996 vtkPlaneSource* planeSource = plane->myPlaneSource;
997 float * planeNormal = planeSource->GetNormal();
998 gp_Dir normal(planeNormal[0], planeNormal[1], planeNormal[2]);
1000 // find a grid axis most co-directed with plane normal
1001 // and cartesian axis most co-directed with plane normal
1002 int i, maxAx = 0, gridAxId = 0;
1003 gp_Dir dir, gridDir;
1005 const vector<float> *curValues, *values = 0;
1006 VISU::Result_i* result = myPrs3d->GetResult();
1007 for (i = 0; i < 3; ++i) {
1008 VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) i;
1009 curValues = result->GetAxisInfo(myPrs3d->GetMeshName(), axis, dir);
1011 double dot = normal * dir;
1012 if (Abs(dot) > Abs(maxDot)) {
1019 if (Abs (planeNormal[ maxAx ]) < Abs (planeNormal[ i ]))
1022 gp_XYZ axDir(0,0,0);
1023 axDir.SetCoord(maxAx + 1, 1.);
1026 double v = SpinBoxDistance->value();
1028 bool reverse = (normal * axDir < 0); // normal and axis are opposite
1029 if (gridDir * axDir < 0) // grid dir and axis are opposite
1033 for (i = 0; i < values->size(); ++i)
1034 if ((*values)[ i ] > v)
1036 if (i == values->size())
1038 if (i != 0 && (*values)[ i ] - v > v - (*values)[ i - 1])
1041 // set control values
1042 myIsSelectPlane = true;
1043 CheckBoxIJKPlaneReverse->setChecked(normal * axDir < 0);
1044 SpinBoxIJKIndex->setValue(i);
1045 ButtonGroupIJKAxis->setButton(gridAxId);
1046 onIJKAxisChanged(gridAxId); // update label and range of index
1047 myIsSelectPlane = false;
1049 SetCurrentPlaneIJKParam();
1052 //=================================================================================
1053 // function : isStructured
1054 // purpose : return true if mesh is structured
1055 //=================================================================================
1056 bool VisuGUI_ClippingDlg::isStructured() const
1058 VISU::Result_i* result = myPrs3d ? myPrs3d->GetResult() : 0;
1061 return result->GetAxisInfo(myPrs3d->GetMeshName(),
1062 VISU::Result_i::AXIS_X,
1068 //=================================================================================
1069 // function : onIJKAxisChanged
1070 // purpose : update Index range and call SetCurrentPlaneParam()
1071 //=================================================================================
1072 void VisuGUI_ClippingDlg::onIJKAxisChanged(int axisId)
1076 VISU::Result_i* result = myPrs3d ? myPrs3d->GetResult() : 0;
1078 VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) axisId;
1080 const vector<float> * indices = result->GetAxisInfo(myPrs3d->GetMeshName(),
1083 maxIndex = indices->size() - 1;
1085 QString text = tr("LBL_IJK_INDEX_TO_arg").arg(maxIndex);
1086 TextLabelIJKIndex->setText(text);
1087 SpinBoxIJKIndex->setRange(0, maxIndex);
1089 if (SpinBoxIJKIndex->value() > maxIndex)
1090 SpinBoxIJKIndex->setValue(0);
1092 SetCurrentPlaneIJKParam();
1095 //=================================================================================
1096 // function : OnPreviewToggle()
1098 //=================================================================================
1099 void VisuGUI_ClippingDlg::OnPreviewToggle (bool theIsToggled)
1101 std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(theIsToggled));
1102 if (SVTK_ViewWindow* vw = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI))
1103 VISU::RenderViewWindow(vw);