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()
214 myViewWindow->RemoveActor(myActor);
218 myMapper->RemoveAllInputs();
221 myPlaneSource->UnRegisterAllOutputs();
222 myPlaneSource->Delete();
225 struct TSetVisiblity {
226 TSetVisiblity(int theIsVisible): myIsVisible(theIsVisible){}
227 void operator()(VISU::TVTKPlane& theOrientedPlane){
228 theOrientedPlane->myActor->SetVisibility(myIsVisible);
233 //=================================================================================
234 // class : VisuGUI_ClippingDlg()
237 //=================================================================================
238 VisuGUI_ClippingDlg::VisuGUI_ClippingDlg (VisuGUI* theModule,
242 : QDialog(VISU::GetDesktop(theModule), name, modal, WStyle_Customize |
243 WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
244 mySelectionMgr(VISU::GetSelectionMgr(theModule)),
248 setName("VisuGUI_ClippingDlg");
249 setCaption(tr("TITLE"));
250 setSizeGripEnabled(TRUE);
251 QGridLayout* VisuGUI_ClippingDlgLayout = new QGridLayout(this);
252 VisuGUI_ClippingDlgLayout->setSpacing(6);
253 VisuGUI_ClippingDlgLayout->setMargin(11);
255 // Controls for selecting, creating, deleting planes
256 QGroupBox* GroupPlanes = new QGroupBox (this, "GroupPlanes");
257 GroupPlanes->setTitle(tr("GRP_PLANES"));
258 GroupPlanes->setColumnLayout(0, Qt::Vertical);
259 GroupPlanes->layout()->setSpacing(0);
260 GroupPlanes->layout()->setMargin(0);
261 QGridLayout* GroupPlanesLayout = new QGridLayout (GroupPlanes->layout());
262 GroupPlanesLayout->setAlignment(Qt::AlignTop);
263 GroupPlanesLayout->setSpacing(6);
264 GroupPlanesLayout->setMargin(11);
266 ComboBoxPlanes = new QComboBox (GroupPlanes, "ComboBoxPlanes");
267 GroupPlanesLayout->addWidget(ComboBoxPlanes, 0, 0);
269 QSpacerItem* spacerGP = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
270 GroupPlanesLayout->addItem(spacerGP, 0, 1);
272 buttonNew = new QPushButton (GroupPlanes, "buttonNew");
273 buttonNew->setText(tr("BUT_NEW"));
274 GroupPlanesLayout->addWidget(buttonNew, 0, 2);
276 buttonDelete = new QPushButton(GroupPlanes, "buttonDelete");
277 buttonDelete->setText(tr("BUT_DELETE"));
278 GroupPlanesLayout->addWidget(buttonDelete, 0, 3);
280 // Controls for defining plane parameters
283 QGroupBox* GroupParameters = new QGroupBox(this, "GroupParameters");
284 GroupParameters->setTitle(tr("GRP_PARAMETERS"));
285 GroupParameters->setColumnLayout(0, Qt::Vertical);
286 GroupParameters->layout()->setSpacing(0);
287 GroupParameters->layout()->setMargin(0);
288 QGridLayout* GroupParametersLayout = new QGridLayout (GroupParameters->layout());
289 GroupParametersLayout->setAlignment(Qt::AlignTop);
290 GroupParametersLayout->setSpacing(6);
291 GroupParametersLayout->setMargin(11);
293 TabPane = new QTabWidget (GroupParameters);
294 TabPane->addTab(createParamsTab() , tr("TAB_NON_STRUCTURED"));
295 TabPane->addTab(createIJKParamsTab(), tr("TAB_IJK_STRUCTURED"));
296 GroupParametersLayout->addWidget(TabPane, 0, 0);
298 // "Show preview" and "Auto Apply" check boxes
300 PreviewCheckBox = new QCheckBox (tr("SHOW_PREVIEW_CHK"), this);
301 PreviewCheckBox->setChecked(true);
303 AutoApplyCheckBox = new QCheckBox (tr("AUTO_APPLY_CHK"), this);
304 AutoApplyCheckBox->setChecked(false);
306 // Controls for "Ok", "Apply" and "Close" button
307 QGroupBox* GroupButtons = new QGroupBox (this, "GroupButtons");
308 GroupButtons->setSizePolicy(QSizePolicy((QSizePolicy::SizeType)7,
309 (QSizePolicy::SizeType)0, 0, 0,
310 GroupButtons->sizePolicy().hasHeightForWidth()));
311 GroupButtons->setGeometry(QRect(10, 10, 281, 48));
312 //GroupButtons->setTitle(tr(""));
313 GroupButtons->setColumnLayout(0, Qt::Vertical);
314 GroupButtons->layout()->setSpacing(0);
315 GroupButtons->layout()->setMargin(0);
316 QGridLayout* GroupButtonsLayout = new QGridLayout (GroupButtons->layout());
317 GroupButtonsLayout->setAlignment(Qt::AlignTop);
318 GroupButtonsLayout->setSpacing(6);
319 GroupButtonsLayout->setMargin(11);
320 buttonHelp = new QPushButton (GroupButtons, "buttonHelp");
321 buttonHelp->setText(tr("BUT_HELP"));
322 buttonHelp->setAutoDefault(TRUE);
323 GroupButtonsLayout->addWidget(buttonHelp, 0, 4);
324 buttonCancel = new QPushButton (GroupButtons, "buttonCancel");
325 buttonCancel->setText(tr("BUT_CLOSE"));
326 buttonCancel->setAutoDefault(TRUE);
327 GroupButtonsLayout->addWidget(buttonCancel, 0, 3);
328 buttonApply = new QPushButton (GroupButtons, "buttonApply");
329 buttonApply->setText(tr("BUT_APPLY"));
330 buttonApply->setAutoDefault(TRUE);
331 GroupButtonsLayout->addWidget(buttonApply, 0, 1);
332 QSpacerItem* spacer_9 = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
333 GroupButtonsLayout->addItem(spacer_9, 0, 2);
334 buttonOk = new QPushButton (GroupButtons, "buttonOk");
335 buttonOk->setText(tr("BUT_OK"));
336 buttonOk->setAutoDefault(TRUE);
337 buttonOk->setDefault(TRUE);
338 GroupButtonsLayout->addWidget(buttonOk, 0, 0);
340 VisuGUI_ClippingDlgLayout->addMultiCellWidget(GroupPlanes, 0, 0, 0, 1);
341 VisuGUI_ClippingDlgLayout->addMultiCellWidget(GroupParameters, 1, 1, 0, 1);
342 VisuGUI_ClippingDlgLayout->addWidget(PreviewCheckBox, 2, 0);
343 VisuGUI_ClippingDlgLayout->addWidget(AutoApplyCheckBox, 2, 1);
344 VisuGUI_ClippingDlgLayout->addMultiCellWidget(GroupButtons, 3, 3, 0, 1);
347 VISU::RangeStepAndValidator(SpinBoxDistance, 0.0, 1.0, 0.01, 3);
348 VISU::RangeStepAndValidator(SpinBoxRot1, -180.0, 180.0, 1, 3);
349 VISU::RangeStepAndValidator(SpinBoxRot2, -180.0, 180.0, 1, 3);
351 ComboBoxOrientation->insertItem(tr("PARALLEL_XOY_COMBO_ITEM"));
352 ComboBoxOrientation->insertItem(tr("PARALLEL_YOZ_COMBO_ITEM"));
353 ComboBoxOrientation->insertItem(tr("PARALLEL_ZOX_COMBO_ITEM"));
355 SpinBoxDistance->setValue(0.5);
358 myIsSelectPlane = false;
359 onSelectionChanged();
361 // signals and slots connections :
362 connect(ComboBoxPlanes , SIGNAL(activated(int)) , this, SLOT(onSelectPlane(int)));
363 connect(buttonNew , SIGNAL(clicked()) , this, SLOT(ClickOnNew()));
364 connect(buttonDelete , SIGNAL(clicked()) , this, SLOT(ClickOnDelete()));
365 connect(ComboBoxOrientation , SIGNAL(activated(int)) , this, SLOT(onSelectOrientation(int)));
366 connect(SpinBoxDistance , SIGNAL(valueChanged(double)) , this, SLOT(SetCurrentPlaneParam()));
367 connect(SpinBoxRot1 , SIGNAL(valueChanged(double)) , this, SLOT(SetCurrentPlaneParam()));
368 connect(SpinBoxRot2 , SIGNAL(valueChanged(double)) , this, SLOT(SetCurrentPlaneParam()));
369 connect(ButtonGroupIJKAxis , SIGNAL(clicked(int)) , this, SLOT(onIJKAxisChanged(int)));
370 connect(SpinBoxIJKIndex , SIGNAL(valueChanged(int)) , this, SLOT(SetCurrentPlaneIJKParam()));
371 connect(CheckBoxIJKPlaneReverse, SIGNAL(toggled(bool)) , this, SLOT(SetCurrentPlaneIJKParam()));
372 connect(TabPane , SIGNAL(currentChanged (QWidget*)), this, SLOT(onTabChanged(QWidget*)));
374 connect(PreviewCheckBox , SIGNAL(toggled(bool)), this, SLOT(OnPreviewToggle(bool)));
375 connect(AutoApplyCheckBox, SIGNAL(toggled(bool)), this, SLOT(ClickOnApply()));
377 connect(buttonOk , SIGNAL(clicked()), this, SLOT(ClickOnOk()));
378 connect(buttonApply , SIGNAL(clicked()), this, SLOT(ClickOnApply()));
379 connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()));
380 connect(buttonHelp , SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
382 connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionChanged()));
387 //=================================================================================
388 // function : ~VisuGUI_ClippingDlg()
390 //=================================================================================
391 VisuGUI_ClippingDlg::~VisuGUI_ClippingDlg()
393 // no need to delete child widgets, Qt does it all for us
394 std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
395 VISU::RenderViewWindow(VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI));
398 //=================================================================================
399 // function : createParamsTab
401 //=================================================================================
402 QWidget* VisuGUI_ClippingDlg::createParamsTab()
404 QFrame* GroupParameters = new QFrame(this);
405 QGridLayout* GroupParametersLayout = new QGridLayout(GroupParameters);
406 GroupParametersLayout->setAlignment(Qt::AlignTop);
407 GroupParametersLayout->setSpacing(6);
408 GroupParametersLayout->setMargin(11);
410 TextLabelOrientation = new QLabel(GroupParameters, "TextLabelOrientation");
411 TextLabelOrientation->setText(tr("LBL_ORIENTATION"));
412 GroupParametersLayout->addWidget(TextLabelOrientation, 0, 0);
414 ComboBoxOrientation = new QComboBox(GroupParameters, "ComboBoxOrientation");
415 GroupParametersLayout->addWidget(ComboBoxOrientation, 0, 1);
417 TextLabelDistance = new QLabel(GroupParameters, "TextLabelDistance");
418 TextLabelDistance->setText(tr("LBL_DISTANCE"));
419 GroupParametersLayout->addWidget(TextLabelDistance, 1, 0);
421 SpinBoxDistance = new QtxDblSpinBox(GroupParameters, "SpinBoxDistance");
422 GroupParametersLayout->addWidget(SpinBoxDistance, 1, 1);
424 TextLabelRot1 = new QLabel(GroupParameters, "TextLabelRot1");
425 TextLabelRot1->setText(tr("LBL_ROTATION_YZ"));
426 GroupParametersLayout->addWidget(TextLabelRot1, 2, 0);
428 SpinBoxRot1 = new QtxDblSpinBox(GroupParameters, "SpinBoxRot1");
429 GroupParametersLayout->addWidget(SpinBoxRot1, 2, 1);
431 TextLabelRot2 = new QLabel(GroupParameters, "TextLabelRot2");
432 TextLabelRot2->setText(tr("LBL_ROTATION_XZ"));
433 GroupParametersLayout->addWidget(TextLabelRot2, 3, 0);
435 SpinBoxRot2 = new QtxDblSpinBox(GroupParameters, "SpinBoxRot2");
436 GroupParametersLayout->addWidget(SpinBoxRot2, 3, 1);
438 return GroupParameters;
441 //=================================================================================
442 // function : createIJKParamsTab
444 //=================================================================================
445 QWidget* VisuGUI_ClippingDlg::createIJKParamsTab()
448 WidgetIJKTab = new QFrame(this);
449 QGridLayout* IJKParametersLayout = new QGridLayout(WidgetIJKTab);
450 IJKParametersLayout->setAlignment(Qt::AlignTop);
451 IJKParametersLayout->setSpacing(6);
452 IJKParametersLayout->setMargin(11);
455 ButtonGroupIJKAxis = new QHButtonGroup (tr("GRP_IJK_AXIS"), WidgetIJKTab);
456 new QRadioButton (tr("I_RADIO_BTN"), ButtonGroupIJKAxis); // 0
457 new QRadioButton (tr("J_RADIO_BTN"), ButtonGroupIJKAxis); // 1
458 new QRadioButton (tr("K_RADIO_BTN"), ButtonGroupIJKAxis); // 2
459 ButtonGroupIJKAxis->setButton(0);
462 TextLabelIJKIndex = new QLabel(WidgetIJKTab, "TextLabelIJKIndex");
463 TextLabelIJKIndex->setText(tr("LBL_IJK_INDEX"));
464 SpinBoxIJKIndex = new QSpinBox(WidgetIJKTab, "SpinBoxIJKIndex");
467 CheckBoxIJKPlaneReverse = new QCheckBox (tr("REVERSE_NORMAL_CHK"), WidgetIJKTab);
468 CheckBoxIJKPlaneReverse->setChecked(false);
470 IJKParametersLayout->addMultiCellWidget(ButtonGroupIJKAxis, 0, 0, 0, 1);
471 IJKParametersLayout->addWidget(TextLabelIJKIndex, 1, 0);
472 IJKParametersLayout->addWidget(SpinBoxIJKIndex, 1, 1);
473 IJKParametersLayout->addWidget(CheckBoxIJKPlaneReverse, 2, 0);
478 //=================================================================================
479 // function : ClickOnApply()
481 //=================================================================================
482 void VisuGUI_ClippingDlg::ClickOnApply()
487 if (SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI)) {
488 SUIT_OverrideCursor wc;
490 QWidget *aCurrWid = this->focusWidget();
491 aCurrWid->clearFocus();
492 aCurrWid->setFocus();
494 // Save clipping planes, currently applied to the presentation
495 // to enable restoring this state in case of failure.
496 // Refer to bugs IPAL8849, IPAL8850 for more information.
497 typedef vtkSmartPointer<vtkPlane> TPln;
498 typedef std::vector<TPln> TPlns;
499 bool isFailed = false;
501 int iopl = 0, nbOldPlanes = myPrs3d->GetNumberOfClippingPlanes();
502 for (; iopl < nbOldPlanes; iopl++) {
503 anOldPlanes.push_back(myPrs3d->GetClippingPlane(iopl));
506 // Try to apply new clipping
507 myPrs3d->RemoveAllClippingPlanes();
509 VISU::TPlanes::iterator anIter = myPlanes.begin();
510 for (; anIter != myPlanes.end(); anIter++) {
511 OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow);
512 anOrientedPlane->ShallowCopy(anIter->GetPointer());
513 if (!myPrs3d->AddClippingPlane(anOrientedPlane)) {
516 anOrientedPlane->Delete();
519 // Check contents of the resulting (clipped) presentation data
521 VISU_PipeLine* aPL = myPrs3d->GetPL();
522 VISU_PipeLine::TMapper* aM = aPL->GetMapper();
523 vtkDataSet* aPrsData = aM->GetInput();
525 if (aPrsData->GetNumberOfCells() < 1) {
531 // Restore previous clipping state because of failure.
532 myPrs3d->RemoveAllClippingPlanes();
534 TPlns::iterator anOldIter = anOldPlanes.begin();
535 for (; anOldIter != anOldPlanes.end(); anOldIter++) {
536 myPrs3d->AddClippingPlane(anOldIter->GetPointer());
539 SUIT_MessageBox::warn1(VISU::GetDesktop(myVisuGUI),
541 tr("WRN_EMPTY_RESULTING_PRS"),
545 //VISU::RenderViewWindow(aViewWindow);
546 VISU::RepaintViewWindows(myVisuGUI, myIO);
550 //=================================================================================
551 // function : ClickOnOk()
553 //=================================================================================
554 void VisuGUI_ClippingDlg::ClickOnOk()
560 //=================================================================================
561 // function : ClickOnCancel()
563 //=================================================================================
564 void VisuGUI_ClippingDlg::ClickOnCancel()
569 //=================================================================================
570 // function : ClickOnHelp()
572 //=================================================================================
573 void VisuGUI_ClippingDlg::ClickOnHelp()
575 QString aHelpFileName = "clipping.htm";
576 LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
578 app->onHelpContextModule(myVisuGUI ? app->moduleName(myVisuGUI->moduleName()) : QString(""), aHelpFileName);
580 SUIT_MessageBox::warn1(0, QObject::tr("WRN_WARNING"),
581 QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
582 arg(app->resourceMgr()->stringValue("ExternalBrowser", "application")).arg(aHelpFileName),
583 QObject::tr("BUT_OK"));
587 //=================================================================================
588 // function : onSelectionChanged()
589 // purpose : Called when selection is changed
590 //=================================================================================
591 void VisuGUI_ClippingDlg::onSelectionChanged()
593 if (SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI)) {
594 Handle(SALOME_InteractiveObject) anIO;
595 CORBA::Object_var anObject = VISU::GetSelectedObj(myVisuGUI, &anIO);
597 if (CORBA::is_nil(anObject)) return;
598 PortableServer::ServantBase_var aServant = VISU::GetServant(anObject);
599 if (!aServant.in()) return;
601 myPrs3d = dynamic_cast<VISU::Prs3d_i*>(aServant.in());
603 std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
606 CORBA::Float anOffset[3];
607 myPrs3d->GetOffset(anOffset[0],anOffset[1],anOffset[2]);
609 vtkIdType anId = 0, anEnd = myPrs3d->GetNumberOfClippingPlanes();
610 for (; anId < anEnd; anId++) {
611 if (vtkImplicitFunction* aFunction = myPrs3d->GetClippingPlane(anId)) {
612 if (OrientedPlane* aPlane = OrientedPlane::SafeDownCast(aFunction)) {
613 OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow);
614 VISU::TVTKPlane aTVTKPlane(anOrientedPlane);
615 anOrientedPlane->Delete();
616 aTVTKPlane->ShallowCopy(aPlane);
617 aTVTKPlane->myActor->SetPosition(anOffset[0],anOffset[1],anOffset[2]);
618 myPlanes.push_back(aTVTKPlane);
623 std::for_each(myPlanes.begin(),myPlanes.end(),
624 TSetVisiblity(PreviewCheckBox->isChecked()));
627 // enable/disable IJK tab
628 TabPane->setTabEnabled(WidgetIJKTab, isStructured());
630 VISU::RenderViewWindow(aViewWindow);
634 //=================================================================================
635 // function : onSelectPlane()
637 //=================================================================================
638 void VisuGUI_ClippingDlg::onSelectPlane(int theIndex)
640 if (!myPrs3d || myPlanes.empty())
643 OrientedPlane* aPlane = myPlanes[theIndex].GetPointer();
646 VISU::Orientation anOrientation = aPlane->GetOrientation();
649 double aRot[2] = {aPlane->myAngle[0], aPlane->myAngle[1]};
651 // Set plane parameters in the dialog
652 myIsSelectPlane = true;
653 setDistance(aPlane->GetDistance());
654 setRotation(aRot[0], aRot[1]);
656 switch (anOrientation) {
657 case VISU::XY: item = 0; break;
658 case VISU::YZ: item = 1; break;
659 case VISU::ZX: item = 2; break;
661 ComboBoxOrientation->setCurrentItem(item);
663 bool isIJK = (TabPane->currentPage() == WidgetIJKTab);
665 setIJKByNonStructured();
667 onSelectOrientation(item);
669 myIsSelectPlane = false;
672 //=================================================================================
673 // function : ClickOnNew()
675 //=================================================================================
676 void VisuGUI_ClippingDlg::ClickOnNew()
678 if(!AutoApplyCheckBox->isChecked())
684 if (SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI)) {
685 OrientedPlane* aPlane = OrientedPlane::New(aViewWindow);
686 VISU::TVTKPlane aTVTKPlane(aPlane);
687 myPlanes.push_back(aTVTKPlane);
689 CORBA::Float anOffset[3];
690 myPrs3d->GetOffset(anOffset[0],anOffset[1],anOffset[2]);
691 aTVTKPlane->myActor->SetPosition(anOffset[0],anOffset[1],anOffset[2]);
693 if (PreviewCheckBox->isChecked())
694 aTVTKPlane->myActor->VisibilityOn();
697 SetCurrentPlaneParam();
701 //=================================================================================
702 // function : ClickOnDelete()
704 //=================================================================================
705 void VisuGUI_ClippingDlg::ClickOnDelete()
707 if (!myPrs3d || myPlanes.empty())
710 int aPlaneIndex = ComboBoxPlanes->currentItem();
712 VISU::TPlanes::iterator anIter = myPlanes.begin() + aPlaneIndex;
713 anIter->GetPointer()->myActor->SetVisibility(false);
714 myPlanes.erase(anIter);
716 if(AutoApplyCheckBox->isChecked())
720 if (SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI))
721 VISU::RenderViewWindow(aViewWindow);
724 //=================================================================================
725 // function : onSelectOrientation()
727 //=================================================================================
728 void VisuGUI_ClippingDlg::onSelectOrientation(int theItem)
730 if (myPlanes.empty())
734 TextLabelRot1->setText(tr("LBL_ROTATION_YZ"));
735 TextLabelRot2->setText(tr("LBL_ROTATION_XZ"));
737 else if (theItem == 1) {
738 TextLabelRot1->setText(tr("LBL_ROTATION_ZX"));
739 TextLabelRot2->setText(tr("LBL_ROTATION_YX"));
741 else if (theItem == 2) {
742 TextLabelRot1->setText(tr("LBL_ROTATION_XY"));
743 TextLabelRot2->setText(tr("LBL_ROTATION_ZY"));
746 if((QComboBox*)sender() == ComboBoxOrientation)
747 SetCurrentPlaneParam();
750 //=================================================================================
751 // function : Sinchronize()
752 // purpose : update control values according to plane selection
753 //=================================================================================
754 void VisuGUI_ClippingDlg::Sinchronize()
756 int aNbPlanes = myPlanes.size();
757 ComboBoxPlanes->clear();
760 for (int i = 1; i<=aNbPlanes; i++) {
761 aName = QString(tr("PLANES_COMBO_ITEM_i")).arg(i);
762 ComboBoxPlanes->insertItem(aName);
765 int aPos = ComboBoxPlanes->count() - 1;
766 ComboBoxPlanes->setCurrentItem(aPos);
768 bool anIsControlsEnable = (aPos >= 0);
769 if (anIsControlsEnable) {
772 ComboBoxPlanes->insertItem(tr("PLANES_COMBO_ITEM_no"));
773 SpinBoxRot1->setValue(0.0);
774 SpinBoxRot2->setValue(0.0);
775 SpinBoxDistance->setValue(0.5);
778 buttonDelete ->setEnabled(anIsControlsEnable);
779 buttonApply ->setEnabled(anIsControlsEnable);
780 PreviewCheckBox ->setEnabled(anIsControlsEnable);
781 AutoApplyCheckBox ->setEnabled(anIsControlsEnable);
783 ComboBoxOrientation ->setEnabled(anIsControlsEnable);
784 SpinBoxDistance ->setEnabled(anIsControlsEnable);
785 SpinBoxRot1 ->setEnabled(anIsControlsEnable);
786 SpinBoxRot2 ->setEnabled(anIsControlsEnable);
788 ButtonGroupIJKAxis ->setEnabled(anIsControlsEnable);
789 SpinBoxIJKIndex ->setEnabled(anIsControlsEnable);
790 CheckBoxIJKPlaneReverse->setEnabled(anIsControlsEnable);
793 //=================================================================================
794 // function : setRotation()
796 //=================================================================================
797 void VisuGUI_ClippingDlg::setRotation(const double theRot1, const double theRot2)
799 SpinBoxRot1->setValue(theRot1);
800 SpinBoxRot2->setValue(theRot2);
803 //=================================================================================
804 // function : SetCurrentPlaneParam()
806 //=================================================================================
807 void VisuGUI_ClippingDlg::SetCurrentPlaneParam()
809 if (myPlanes.empty() || myIsSelectPlane)
812 int aCurPlaneIndex = ComboBoxPlanes->currentItem();
814 OrientedPlane* aPlane = myPlanes[aCurPlaneIndex].GetPointer();
816 vtkFloatingPointType aNormal[3];
817 VISU::Orientation anOrientation;
818 vtkFloatingPointType aDir[3][3] = {{0, 0, 0}, {0, 0, 0}};
820 static double aCoeff = vtkMath::Pi()/180.0;
822 vtkFloatingPointType aRot[2] = {getRotation1(), getRotation2()};
823 aPlane->myAngle[0] = aRot[0];
824 aPlane->myAngle[1] = aRot[1];
826 vtkFloatingPointType anU[2] = {cos(aCoeff*aRot[0]), cos(aCoeff*aRot[1])};
827 vtkFloatingPointType aV[2] = {sqrt(1.0-anU[0]*anU[0]), sqrt(1.0-anU[1]*anU[1])};
828 aV[0] = aRot[0] > 0? aV[0]: -aV[0];
829 aV[1] = aRot[1] > 0? aV[1]: -aV[1];
831 switch (ComboBoxOrientation->currentItem()) {
833 anOrientation = VISU::XY;
843 anOrientation = VISU::YZ;
853 anOrientation = VISU::ZX;
864 vtkMath::Cross(aDir[1],aDir[0],aNormal);
865 vtkMath::Normalize(aNormal);
866 vtkMath::Cross(aNormal,aDir[1],aDir[0]);
869 aPlane->SetOrientation(anOrientation);
870 aPlane->SetDistance(getDistance());
872 myPrs3d->SetPlaneParam(aNormal, 1. - getDistance(), aPlane);
874 vtkDataSet* aDataSet = myPrs3d->GetInput();
875 vtkFloatingPointType *aPnt = aDataSet->GetCenter();
877 vtkFloatingPointType* anOrigin = aPlane->GetOrigin();
878 vtkFloatingPointType aDel = aDataSet->GetLength()/2.0;
880 vtkFloatingPointType aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel},
881 {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}};
882 vtkFloatingPointType aParam, aPnt0[3], aPnt1[3], aPnt2[3];
884 vtkFloatingPointType aPnt01[3] = {aPnt[0] - aDelta[0][0] - aDelta[1][0],
885 aPnt[1] - aDelta[0][1] - aDelta[1][1],
886 aPnt[2] - aDelta[0][2] - aDelta[1][2]};
887 vtkFloatingPointType aPnt02[3] = {aPnt01[0] + aNormal[0],
888 aPnt01[1] + aNormal[1],
889 aPnt01[2] + aNormal[2]};
890 vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0);
892 vtkFloatingPointType aPnt11[3] = {aPnt[0] - aDelta[0][0] + aDelta[1][0],
893 aPnt[1] - aDelta[0][1] + aDelta[1][1],
894 aPnt[2] - aDelta[0][2] + aDelta[1][2]};
895 vtkFloatingPointType aPnt12[3] = {aPnt11[0] + aNormal[0],
896 aPnt11[1] + aNormal[1],
897 aPnt11[2] + aNormal[2]};
898 vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1);
900 vtkFloatingPointType aPnt21[3] = {aPnt[0] + aDelta[0][0] - aDelta[1][0],
901 aPnt[1] + aDelta[0][1] - aDelta[1][1],
902 aPnt[2] + aDelta[0][2] - aDelta[1][2]};
903 vtkFloatingPointType aPnt22[3] = {aPnt21[0] + aNormal[0],
904 aPnt21[1] + aNormal[1],
905 aPnt21[2] + aNormal[2]};
906 vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2);
908 vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource;
909 aPlaneSource->SetNormal(aNormal[0],aNormal[1],aNormal[2]);
910 aPlaneSource->SetOrigin(aPnt0[0],aPnt0[1],aPnt0[2]);
911 aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]);
912 aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]);
914 if (AutoApplyCheckBox->isChecked())
917 if (SVTK_ViewWindow* vw = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI))
918 VISU::RenderViewWindow(vw);
921 //=================================================================================
922 // function : onTabChanged
924 //=================================================================================
925 void VisuGUI_ClippingDlg::onTabChanged(QWidget* newTab)
927 if (newTab == WidgetIJKTab) // IJK
928 setIJKByNonStructured();
930 // set correct labels of rotation spin boxes
931 onSelectOrientation(ComboBoxOrientation->currentItem());
935 //=================================================================================
936 // function : SetCurrentPlaneIJKParam
937 // purpose : set non structured parameters by IJK parameters
938 //=================================================================================
939 void VisuGUI_ClippingDlg::SetCurrentPlaneIJKParam()
941 if (myPlanes.empty() || myIsSelectPlane || !WidgetIJKTab->isEnabled())
944 VISU::Result_i* result = myPrs3d ? myPrs3d->GetResult() : 0;
949 int i, axId = ButtonGroupIJKAxis->id (ButtonGroupIJKAxis->selected());
950 VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) axId;
952 const vector<vtkFloatingPointType> * values =
953 result->GetAxisInfo(myPrs3d->GetMeshName(), axis, dir);
958 int index = SpinBoxIJKIndex->value();
959 vtkFloatingPointType distance = 0;
960 if (index < values->size())
961 distance = (*values)[ index ];
963 // find id of axis closest to dir
967 double cos[3] = { gp::DZ() * dir, gp::DX() * dir, gp::DY() * dir };
969 for (i = 0; i < 3; ++i) {
970 if (Abs(cos[ i ]) > Abs (maxCos)) {
975 // find rotation angles
976 vtkFloatingPointType angle[2];
978 (axId == 0) ? 2 : axId - 1,
979 (axId == 2) ? 0 : axId + 1
981 static double aCoeff = 180.0/vtkMath::Pi();
982 for (i = 0; i < 2; ++i) {
983 vtkFloatingPointType cosin = cos[ rotId[ i ]];
986 angle[ i ] = asin(cosin) * aCoeff;
988 angle[ i ] += 180. * (angle[ i ] < 0 ? 1. : -1.);
990 if (CheckBoxIJKPlaneReverse->isChecked()) {
991 angle[ 0 ] += 180. * (angle[ 0 ] < 0 ? 1. : -1.);
992 distance = 1. - distance;
995 distance = 1. - distance;
998 myIsSelectPlane = true;
999 ComboBoxOrientation->setCurrentItem(axId);
1000 setRotation(-angle[0], -angle[1]);
1001 setDistance(distance);
1002 myIsSelectPlane = false;
1004 SetCurrentPlaneParam();
1007 //=================================================================================
1008 // function : setIJKByNonStructured
1009 // purpose : convert current non structured parameters to structured ones
1010 //=================================================================================
1011 void VisuGUI_ClippingDlg::setIJKByNonStructured()
1013 if (!myPrs3d || myPlanes.empty() || !myPrs3d->GetResult())
1017 int planeIndex = ComboBoxPlanes->currentItem();
1018 OrientedPlane* plane = myPlanes[ planeIndex ].GetPointer();
1019 vtkPlaneSource* planeSource = plane->myPlaneSource;
1020 vtkFloatingPointType * planeNormal = planeSource->GetNormal();
1021 gp_Dir normal(planeNormal[0], planeNormal[1], planeNormal[2]);
1023 // find a grid axis most co-directed with plane normal
1024 // and cartesian axis most co-directed with plane normal
1025 int i, maxAx = 0, gridAxId = 0;
1026 gp_Dir dir, gridDir;
1028 const vector<vtkFloatingPointType> *curValues, *values = 0;
1029 VISU::Result_i* result = myPrs3d->GetResult();
1030 for (i = 0; i < 3; ++i) {
1031 VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) i;
1032 curValues = result->GetAxisInfo(myPrs3d->GetMeshName(), axis, dir);
1034 double dot = normal * dir;
1035 if (Abs(dot) > Abs(maxDot)) {
1042 if (Abs (planeNormal[ maxAx ]) < Abs (planeNormal[ i ]))
1045 gp_XYZ axDir(0,0,0);
1046 axDir.SetCoord(maxAx + 1, 1.);
1049 double v = SpinBoxDistance->value();
1051 bool reverse = (normal * axDir < 0); // normal and axis are opposite
1052 if (gridDir * axDir < 0) // grid dir and axis are opposite
1056 for (i = 0; i < values->size(); ++i)
1057 if ((*values)[ i ] > v)
1059 if (i == values->size())
1061 if (i != 0 && (*values)[ i ] - v > v - (*values)[ i - 1])
1064 // set control values
1065 myIsSelectPlane = true;
1066 CheckBoxIJKPlaneReverse->setChecked(normal * axDir < 0);
1067 SpinBoxIJKIndex->setValue(i);
1068 ButtonGroupIJKAxis->setButton(gridAxId);
1069 onIJKAxisChanged(gridAxId); // update label and range of index
1070 myIsSelectPlane = false;
1072 SetCurrentPlaneIJKParam();
1075 //=================================================================================
1076 // function : isStructured
1077 // purpose : return true if mesh is structured
1078 //=================================================================================
1079 bool VisuGUI_ClippingDlg::isStructured() const
1081 VISU::Result_i* result = myPrs3d ? myPrs3d->GetResult() : 0;
1084 return result->GetAxisInfo(myPrs3d->GetMeshName(),
1085 VISU::Result_i::AXIS_X,
1091 //=================================================================================
1092 // function : onIJKAxisChanged
1093 // purpose : update Index range and call SetCurrentPlaneParam()
1094 //=================================================================================
1095 void VisuGUI_ClippingDlg::onIJKAxisChanged(int axisId)
1099 VISU::Result_i* result = myPrs3d ? myPrs3d->GetResult() : 0;
1101 VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) axisId;
1103 const vector<vtkFloatingPointType> * indices = result->GetAxisInfo(myPrs3d->GetMeshName(),
1106 maxIndex = indices->size() - 1;
1108 QString text = tr("LBL_IJK_INDEX_TO_arg").arg(maxIndex);
1109 TextLabelIJKIndex->setText(text);
1110 SpinBoxIJKIndex->setRange(0, maxIndex);
1112 if (SpinBoxIJKIndex->value() > maxIndex)
1113 SpinBoxIJKIndex->setValue(0);
1115 SetCurrentPlaneIJKParam();
1118 //=================================================================================
1119 // function : OnPreviewToggle()
1121 //=================================================================================
1122 void VisuGUI_ClippingDlg::OnPreviewToggle (bool theIsToggled)
1124 std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(theIsToggled));
1125 if (SVTK_ViewWindow* vw = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI))
1126 VISU::RenderViewWindow(vw);