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"
26 #include "VISU_Prs3d_i.hh"
27 #include "VISU_Result_i.hh"
29 #include "VISU_PipeLine.hxx"
31 #include "LightApp_SelectionMgr.h"
33 #include "SVTK_ViewWindow.h"
35 #include "SUIT_Session.h"
36 #include "SUIT_Desktop.h"
37 #include "SUIT_MessageBox.h"
38 #include "SUIT_ResourceMgr.h"
39 #include "SUIT_OverrideCursor.h"
41 #include "SALOME_Actor.h"
45 #include <qpushbutton.h>
46 #include <qcombobox.h>
47 #include <qcheckbox.h>
49 #include <qgroupbox.h>
50 #include <qvalidator.h>
51 #include <qtabwidget.h>
52 #include <qhbuttongroup.h>
53 #include <qradiobutton.h>
58 #include <vtkCamera.h>
59 #include <vtkRenderer.h>
60 #include <vtkDataSet.h>
61 #include <vtkDataSetMapper.h>
62 #include <vtkImplicitFunction.h>
63 #include <vtkPlaneSource.h>
64 #include <vtkPolyData.h>
65 #include <vtkUnstructuredGrid.h>
66 #include <vtkProperty.h>
74 float GetFloat (const QString& theValue, float theDefault)
76 if (theValue.isEmpty()) return theDefault;
77 SUIT_ResourceMgr* aResourceMgr = VISU::GetResourceMgr();
78 QString aValue = aResourceMgr->stringValue("VISU",theValue);
79 if (aValue.isEmpty()) return theDefault;
80 return aValue.toFloat();
83 void RenderViewWindow (SVTK_ViewWindow* vw)
86 vw->getRenderer()->ResetCameraClippingRange();
91 void RangeStepAndValidator (QtxDblSpinBox* theSpinBox, double min, double max,
92 double step, unsigned short decimals)
94 theSpinBox->setRange(min, max);
95 theSpinBox->setLineStep(step);
96 ((QDoubleValidator*)theSpinBox->validator())->setRange(min, max, decimals);
100 //=================================================================================
101 //class : OrientedPlane
103 //=================================================================================
104 class OrientedPlane: public vtkPlane
106 SVTK_ViewWindow* myViewWindow;
108 vtkDataSetMapper* myMapper;
111 static OrientedPlane * New() {
112 return new OrientedPlane();
114 static OrientedPlane * New (SVTK_ViewWindow* vw) {
115 return new OrientedPlane(vw);
117 vtkTypeMacro(OrientedPlane, vtkPlane);
120 VISU::Orientation myOrientation;
124 vtkPlaneSource* myPlaneSource;
125 SALOME_Actor *myActor;
127 void SetOrientation(VISU::Orientation theOrientation) {myOrientation = theOrientation;}
128 VISU::Orientation GetOrientation() {return myOrientation;}
130 void SetDistance(float theDistance) {myDistance = theDistance;}
131 float GetDistance() {return myDistance;}
133 void ShallowCopy(OrientedPlane* theOrientedPlane){
134 SetNormal(theOrientedPlane->GetNormal());
135 SetOrigin(theOrientedPlane->GetOrigin());
137 myOrientation = theOrientedPlane->GetOrientation();
138 myDistance = theOrientedPlane->GetDistance();
140 myAngle[0] = theOrientedPlane->myAngle[0];
141 myAngle[1] = theOrientedPlane->myAngle[1];
143 myPlaneSource->SetNormal(theOrientedPlane->myPlaneSource->GetNormal());
144 myPlaneSource->SetOrigin(theOrientedPlane->myPlaneSource->GetOrigin());
145 myPlaneSource->SetPoint1(theOrientedPlane->myPlaneSource->GetPoint1());
146 myPlaneSource->SetPoint2(theOrientedPlane->myPlaneSource->GetPoint2());
150 OrientedPlane(SVTK_ViewWindow* vw):
151 myOrientation(VISU::XY),
156 myViewWindow->AddActor(myActor);
160 myOrientation(VISU::XY),
168 myPlaneSource = vtkPlaneSource::New();
170 myAngle[0] = myAngle[1] = 0.0;
172 // Create and display actor
173 myMapper = vtkDataSetMapper::New();
174 myMapper->SetInput(myPlaneSource->GetOutput());
176 myActor = SALOME_Actor::New();
177 myActor->VisibilityOff();
178 myActor->PickableOff();
179 myActor->SetInfinitive(true);
180 myActor->SetMapper(myMapper);
182 vtkProperty* aProp = vtkProperty::New();
185 SUIT_ResourceMgr* aResourceMgr = VISU::GetResourceMgr();
187 QColor aFillColor = aResourceMgr->colorValue("SMESH", "fill_color", QColor(0, 170, 255));
188 anRGB[0] = aFillColor.red()/255.;
189 anRGB[1] = aFillColor.green()/255.;
190 anRGB[2] = aFillColor.blue()/255.;
191 aProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
192 aProp->SetOpacity(0.75);
193 myActor->SetProperty(aProp);
196 vtkProperty* aBackProp = vtkProperty::New();
197 QColor aBackFaceColor = aResourceMgr->colorValue("SMESH", "backface_color", QColor(0, 0, 255));//@
198 anRGB[0] = aBackFaceColor.red()/255.;
199 anRGB[1] = aBackFaceColor.green()/255.;
200 anRGB[2] = aBackFaceColor.blue()/255.;
201 aBackProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
202 aBackProp->SetOpacity(0.75);
203 myActor->SetBackfaceProperty(aBackProp);
210 myViewWindow->RemoveActor(myActor);
214 myMapper->RemoveAllInputs();
217 myPlaneSource->UnRegisterAllOutputs();
218 myPlaneSource->Delete();
223 OrientedPlane(const OrientedPlane&);
224 void operator=(const OrientedPlane&);
227 struct TSetVisiblity {
228 TSetVisiblity(int theIsVisible): myIsVisible(theIsVisible){}
229 void operator()(VISU::TVTKPlane& theOrientedPlane){
230 theOrientedPlane->myActor->SetVisibility(myIsVisible);
235 //=================================================================================
236 // class : VisuGUI_ClippingDlg()
239 //=================================================================================
240 VisuGUI_ClippingDlg::VisuGUI_ClippingDlg (VisuGUI* theModule,
244 : QDialog(VISU::GetDesktop(theModule), name, modal, WStyle_Customize |
245 WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
246 mySelectionMgr(VISU::GetSelectionMgr(theModule)),
250 setName("VisuGUI_ClippingDlg");
251 setCaption(tr("TITLE"));
252 setSizeGripEnabled(TRUE);
253 QGridLayout* VisuGUI_ClippingDlgLayout = new QGridLayout(this);
254 VisuGUI_ClippingDlgLayout->setSpacing(6);
255 VisuGUI_ClippingDlgLayout->setMargin(11);
257 // Controls for selecting, creating, deleting planes
258 QGroupBox* GroupPlanes = new QGroupBox (this, "GroupPlanes");
259 GroupPlanes->setTitle(tr("GRP_PLANES"));
260 GroupPlanes->setColumnLayout(0, Qt::Vertical);
261 GroupPlanes->layout()->setSpacing(0);
262 GroupPlanes->layout()->setMargin(0);
263 QGridLayout* GroupPlanesLayout = new QGridLayout (GroupPlanes->layout());
264 GroupPlanesLayout->setAlignment(Qt::AlignTop);
265 GroupPlanesLayout->setSpacing(6);
266 GroupPlanesLayout->setMargin(11);
268 ComboBoxPlanes = new QComboBox (GroupPlanes, "ComboBoxPlanes");
269 GroupPlanesLayout->addWidget(ComboBoxPlanes, 0, 0);
271 QSpacerItem* spacerGP = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
272 GroupPlanesLayout->addItem(spacerGP, 0, 1);
274 buttonNew = new QPushButton (GroupPlanes, "buttonNew");
275 buttonNew->setText(tr("BUT_NEW"));
276 GroupPlanesLayout->addWidget(buttonNew, 0, 2);
278 buttonDelete = new QPushButton(GroupPlanes, "buttonDelete");
279 buttonDelete->setText(tr("BUT_DELETE"));
280 GroupPlanesLayout->addWidget(buttonDelete, 0, 3);
282 // Controls for defining plane parameters
285 QGroupBox* GroupParameters = new QGroupBox(this, "GroupParameters");
286 GroupParameters->setTitle(tr("GRP_PARAMETERS"));
287 GroupParameters->setColumnLayout(0, Qt::Vertical);
288 GroupParameters->layout()->setSpacing(0);
289 GroupParameters->layout()->setMargin(0);
290 QGridLayout* GroupParametersLayout = new QGridLayout (GroupParameters->layout());
291 GroupParametersLayout->setAlignment(Qt::AlignTop);
292 GroupParametersLayout->setSpacing(6);
293 GroupParametersLayout->setMargin(11);
295 TabPane = new QTabWidget (GroupParameters);
296 TabPane->addTab(createParamsTab() , tr("TAB_NON_STRUCTURED"));
297 TabPane->addTab(createIJKParamsTab(), tr("TAB_IJK_STRUCTURED"));
298 GroupParametersLayout->addWidget(TabPane, 0, 0);
300 // "Show preview" and "Auto Apply" check boxes
302 PreviewCheckBox = new QCheckBox (tr("SHOW_PREVIEW_CHK"), this);
303 PreviewCheckBox->setChecked(true);
305 AutoApplyCheckBox = new QCheckBox (tr("AUTO_APPLY_CHK"), this);
306 AutoApplyCheckBox->setChecked(false);
308 // Controls for "Ok", "Apply" and "Close" button
309 QGroupBox* GroupButtons = new QGroupBox (this, "GroupButtons");
310 GroupButtons->setSizePolicy(QSizePolicy((QSizePolicy::SizeType)7,
311 (QSizePolicy::SizeType)0, 0, 0,
312 GroupButtons->sizePolicy().hasHeightForWidth()));
313 GroupButtons->setGeometry(QRect(10, 10, 281, 48));
314 //GroupButtons->setTitle(tr(""));
315 GroupButtons->setColumnLayout(0, Qt::Vertical);
316 GroupButtons->layout()->setSpacing(0);
317 GroupButtons->layout()->setMargin(0);
318 QGridLayout* GroupButtonsLayout = new QGridLayout (GroupButtons->layout());
319 GroupButtonsLayout->setAlignment(Qt::AlignTop);
320 GroupButtonsLayout->setSpacing(6);
321 GroupButtonsLayout->setMargin(11);
322 buttonCancel = new QPushButton (GroupButtons, "buttonCancel");
323 buttonCancel->setText(tr("BUT_CLOSE"));
324 buttonCancel->setAutoDefault(TRUE);
325 GroupButtonsLayout->addWidget(buttonCancel, 0, 3);
326 buttonApply = new QPushButton (GroupButtons, "buttonApply");
327 buttonApply->setText(tr("BUT_APPLY"));
328 buttonApply->setAutoDefault(TRUE);
329 GroupButtonsLayout->addWidget(buttonApply, 0, 1);
330 QSpacerItem* spacer_9 = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
331 GroupButtonsLayout->addItem(spacer_9, 0, 2);
332 buttonOk = new QPushButton (GroupButtons, "buttonOk");
333 buttonOk->setText(tr("BUT_OK"));
334 buttonOk->setAutoDefault(TRUE);
335 buttonOk->setDefault(TRUE);
336 GroupButtonsLayout->addWidget(buttonOk, 0, 0);
338 VisuGUI_ClippingDlgLayout->addMultiCellWidget(GroupPlanes, 0, 0, 0, 1);
339 VisuGUI_ClippingDlgLayout->addMultiCellWidget(GroupParameters, 1, 1, 0, 1);
340 VisuGUI_ClippingDlgLayout->addWidget(PreviewCheckBox, 2, 0);
341 VisuGUI_ClippingDlgLayout->addWidget(AutoApplyCheckBox, 2, 1);
342 VisuGUI_ClippingDlgLayout->addMultiCellWidget(GroupButtons, 3, 3, 0, 1);
345 VISU::RangeStepAndValidator(SpinBoxDistance, 0.0, 1.0, 0.01, 3);
346 VISU::RangeStepAndValidator(SpinBoxRot1, -180.0, 180.0, 1, 3);
347 VISU::RangeStepAndValidator(SpinBoxRot2, -180.0, 180.0, 1, 3);
349 ComboBoxOrientation->insertItem(tr("PARALLEL_XOY_COMBO_ITEM"));
350 ComboBoxOrientation->insertItem(tr("PARALLEL_YOZ_COMBO_ITEM"));
351 ComboBoxOrientation->insertItem(tr("PARALLEL_ZOX_COMBO_ITEM"));
353 SpinBoxDistance->setValue(0.5);
356 myIsSelectPlane = false;
357 onSelectionChanged();
359 // signals and slots connections :
360 connect(ComboBoxPlanes , SIGNAL(activated(int)) , this, SLOT(onSelectPlane(int)));
361 connect(buttonNew , SIGNAL(clicked()) , this, SLOT(ClickOnNew()));
362 connect(buttonDelete , SIGNAL(clicked()) , this, SLOT(ClickOnDelete()));
363 connect(ComboBoxOrientation , SIGNAL(activated(int)) , this, SLOT(onSelectOrientation(int)));
364 connect(SpinBoxDistance , SIGNAL(valueChanged(double)) , this, SLOT(SetCurrentPlaneParam()));
365 connect(SpinBoxRot1 , SIGNAL(valueChanged(double)) , this, SLOT(SetCurrentPlaneParam()));
366 connect(SpinBoxRot2 , SIGNAL(valueChanged(double)) , this, SLOT(SetCurrentPlaneParam()));
367 connect(ButtonGroupIJKAxis , SIGNAL(clicked(int)) , this, SLOT(onIJKAxisChanged(int)));
368 connect(SpinBoxIJKIndex , SIGNAL(valueChanged(int)) , this, SLOT(SetCurrentPlaneIJKParam()));
369 connect(CheckBoxIJKPlaneReverse, SIGNAL(toggled(bool)) , this, SLOT(SetCurrentPlaneIJKParam()));
370 connect(TabPane , SIGNAL(currentChanged (QWidget*)), this, SLOT(onTabChanged(QWidget*)));
372 connect(PreviewCheckBox , SIGNAL(toggled(bool)), this, SLOT(OnPreviewToggle(bool)));
373 connect(AutoApplyCheckBox, SIGNAL(toggled(bool)), this, SLOT(ClickOnApply()));
375 connect(buttonOk , SIGNAL(clicked()), this, SLOT(ClickOnOk()));
376 connect(buttonApply , SIGNAL(clicked()), this, SLOT(ClickOnApply()));
377 connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()));
379 connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionChanged()));
384 //=================================================================================
385 // function : ~VisuGUI_ClippingDlg()
387 //=================================================================================
388 VisuGUI_ClippingDlg::~VisuGUI_ClippingDlg()
390 // no need to delete child widgets, Qt does it all for us
391 std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
392 VISU::RenderViewWindow(VISU::GetViewWindow(myVisuGUI));
395 //=================================================================================
396 // function : createParamsTab
398 //=================================================================================
399 QWidget* VisuGUI_ClippingDlg::createParamsTab()
401 QFrame* GroupParameters = new QFrame(this);
402 QGridLayout* GroupParametersLayout = new QGridLayout(GroupParameters);
403 GroupParametersLayout->setAlignment(Qt::AlignTop);
404 GroupParametersLayout->setSpacing(6);
405 GroupParametersLayout->setMargin(11);
407 TextLabelOrientation = new QLabel(GroupParameters, "TextLabelOrientation");
408 TextLabelOrientation->setText(tr("LBL_ORIENTATION"));
409 GroupParametersLayout->addWidget(TextLabelOrientation, 0, 0);
411 ComboBoxOrientation = new QComboBox(GroupParameters, "ComboBoxOrientation");
412 GroupParametersLayout->addWidget(ComboBoxOrientation, 0, 1);
414 TextLabelDistance = new QLabel(GroupParameters, "TextLabelDistance");
415 TextLabelDistance->setText(tr("LBL_DISTANCE"));
416 GroupParametersLayout->addWidget(TextLabelDistance, 1, 0);
418 SpinBoxDistance = new QtxDblSpinBox(GroupParameters, "SpinBoxDistance");
419 GroupParametersLayout->addWidget(SpinBoxDistance, 1, 1);
421 TextLabelRot1 = new QLabel(GroupParameters, "TextLabelRot1");
422 TextLabelRot1->setText(tr("LBL_ROTATION_YZ"));
423 GroupParametersLayout->addWidget(TextLabelRot1, 2, 0);
425 SpinBoxRot1 = new QtxDblSpinBox(GroupParameters, "SpinBoxRot1");
426 GroupParametersLayout->addWidget(SpinBoxRot1, 2, 1);
428 TextLabelRot2 = new QLabel(GroupParameters, "TextLabelRot2");
429 TextLabelRot2->setText(tr("LBL_ROTATION_XZ"));
430 GroupParametersLayout->addWidget(TextLabelRot2, 3, 0);
432 SpinBoxRot2 = new QtxDblSpinBox(GroupParameters, "SpinBoxRot2");
433 GroupParametersLayout->addWidget(SpinBoxRot2, 3, 1);
435 return GroupParameters;
438 //=================================================================================
439 // function : createIJKParamsTab
441 //=================================================================================
442 QWidget* VisuGUI_ClippingDlg::createIJKParamsTab()
445 WidgetIJKTab = new QFrame(this);
446 QGridLayout* IJKParametersLayout = new QGridLayout(WidgetIJKTab);
447 IJKParametersLayout->setAlignment(Qt::AlignTop);
448 IJKParametersLayout->setSpacing(6);
449 IJKParametersLayout->setMargin(11);
452 ButtonGroupIJKAxis = new QHButtonGroup (tr("GRP_IJK_AXIS"), WidgetIJKTab);
453 new QRadioButton (tr("I_RADIO_BTN"), ButtonGroupIJKAxis); // 0
454 new QRadioButton (tr("J_RADIO_BTN"), ButtonGroupIJKAxis); // 1
455 new QRadioButton (tr("K_RADIO_BTN"), ButtonGroupIJKAxis); // 2
456 ButtonGroupIJKAxis->setButton(0);
459 TextLabelIJKIndex = new QLabel(WidgetIJKTab, "TextLabelIJKIndex");
460 TextLabelIJKIndex->setText(tr("LBL_IJK_INDEX"));
461 SpinBoxIJKIndex = new QSpinBox(WidgetIJKTab, "SpinBoxIJKIndex");
464 CheckBoxIJKPlaneReverse = new QCheckBox (tr("REVERSE_NORMAL_CHK"), WidgetIJKTab);
465 CheckBoxIJKPlaneReverse->setChecked(false);
467 IJKParametersLayout->addMultiCellWidget(ButtonGroupIJKAxis, 0, 0, 0, 1);
468 IJKParametersLayout->addWidget(TextLabelIJKIndex, 1, 0);
469 IJKParametersLayout->addWidget(SpinBoxIJKIndex, 1, 1);
470 IJKParametersLayout->addWidget(CheckBoxIJKPlaneReverse, 2, 0);
475 //=================================================================================
476 // function : ClickOnApply()
478 //=================================================================================
479 void VisuGUI_ClippingDlg::ClickOnApply()
484 if (SVTK_ViewWindow* aViewWindow = VISU::GetViewWindow(myVisuGUI)) {
485 SUIT_OverrideCursor wc;
487 // Save clipping planes, currently applied to the presentation
488 // to enable restoring this state in case of failure.
489 // Refer to bugs IPAL8849, IPAL8850 for more information.
490 typedef vtkSmartPointer<vtkPlane> TPln;
491 typedef std::vector<TPln> TPlns;
492 bool isFailed = false;
494 int iopl = 0, nbOldPlanes = myPrs3d->GetNumberOfClippingPlanes();
495 for (; iopl < nbOldPlanes; iopl++) {
496 anOldPlanes.push_back(myPrs3d->GetClippingPlane(iopl));
499 // Try to apply new clipping
500 myPrs3d->RemoveAllClippingPlanes();
502 VISU::TPlanes::iterator anIter = myPlanes.begin();
503 for (; anIter != myPlanes.end(); anIter++) {
504 OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow);
505 anOrientedPlane->ShallowCopy(anIter->GetPointer());
506 if (!myPrs3d->AddClippingPlane(anOrientedPlane)) {
509 anOrientedPlane->Delete();
512 // Check contents of the resulting (clipped) presentation data
514 VISU_PipeLine* aPL = myPrs3d->GetPL();
515 VISU_PipeLine::TMapper* aM = aPL->GetMapper();
516 vtkDataSet* aPrsData = aM->GetInput();
518 if (aPrsData->GetNumberOfCells() < 1) {
524 // Restore previous clipping state because of failure.
525 myPrs3d->RemoveAllClippingPlanes();
527 TPlns::iterator anOldIter = anOldPlanes.begin();
528 for (; anOldIter != anOldPlanes.end(); anOldIter++) {
529 myPrs3d->AddClippingPlane(anOldIter->GetPointer());
532 SUIT_MessageBox::warn1(VISU::GetDesktop(myVisuGUI),
534 tr("WRN_EMPTY_RESULTING_PRS"),
538 //VISU::RenderViewWindow(aViewWindow);
539 VISU::RepaintViewWindows(myVisuGUI, myIO);
543 //=================================================================================
544 // function : ClickOnOk()
546 //=================================================================================
547 void VisuGUI_ClippingDlg::ClickOnOk()
553 //=================================================================================
554 // function : ClickOnCancel()
556 //=================================================================================
557 void VisuGUI_ClippingDlg::ClickOnCancel()
562 //=================================================================================
563 // function : onSelectionChanged()
564 // purpose : Called when selection is changed
565 //=================================================================================
566 void VisuGUI_ClippingDlg::onSelectionChanged()
568 if (SVTK_ViewWindow* aViewWindow = VISU::GetViewWindow(myVisuGUI)) {
569 Handle(SALOME_InteractiveObject) anIO;
570 CORBA::Object_var anObject = VISU::GetSelectedObj(myVisuGUI, &anIO);
572 if (CORBA::is_nil(anObject)) return;
573 PortableServer::ServantBase_var aServant = VISU::GetServant(anObject);
574 if (!aServant.in()) return;
576 myPrs3d = dynamic_cast<VISU::Prs3d_i*>(aServant.in());
578 std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
582 myPrs3d->GetOffset(anOffset);
584 vtkIdType anId = 0, anEnd = myPrs3d->GetNumberOfClippingPlanes();
585 for (; anId < anEnd; anId++) {
586 if (vtkImplicitFunction* aFunction = myPrs3d->GetClippingPlane(anId)) {
587 if (OrientedPlane* aPlane = OrientedPlane::SafeDownCast(aFunction)) {
588 OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow);
589 VISU::TVTKPlane aTVTKPlane(anOrientedPlane);
590 anOrientedPlane->Delete();
591 aTVTKPlane->ShallowCopy(aPlane);
592 aTVTKPlane->myActor->SetPosition(anOffset);
593 myPlanes.push_back(aTVTKPlane);
598 std::for_each(myPlanes.begin(),myPlanes.end(),
599 TSetVisiblity(PreviewCheckBox->isChecked()));
602 // enable/disable IJK tab
603 TabPane->setTabEnabled(WidgetIJKTab, isStructured());
605 VISU::RenderViewWindow(aViewWindow);
609 //=================================================================================
610 // function : onSelectPlane()
612 //=================================================================================
613 void VisuGUI_ClippingDlg::onSelectPlane(int theIndex)
615 if (!myPrs3d || myPlanes.empty())
618 OrientedPlane* aPlane = myPlanes[theIndex].GetPointer();
621 VISU::Orientation anOrientation = aPlane->GetOrientation();
624 double aRot[2] = {aPlane->myAngle[0], aPlane->myAngle[1]};
626 // Set plane parameters in the dialog
627 myIsSelectPlane = true;
628 setDistance(aPlane->GetDistance());
629 setRotation(aRot[0], aRot[1]);
631 switch (anOrientation) {
632 case VISU::XY: item = 0; break;
633 case VISU::YZ: item = 1; break;
634 case VISU::ZX: item = 2; break;
636 ComboBoxOrientation->setCurrentItem(item);
638 bool isIJK = (TabPane->currentPage() == WidgetIJKTab);
640 setIJKByNonStructured();
642 onSelectOrientation(item);
644 myIsSelectPlane = false;
647 //=================================================================================
648 // function : ClickOnNew()
650 //=================================================================================
651 void VisuGUI_ClippingDlg::ClickOnNew()
656 if (SVTK_ViewWindow* aViewWindow = VISU::GetViewWindow(myVisuGUI)) {
657 OrientedPlane* aPlane = OrientedPlane::New(aViewWindow);
658 VISU::TVTKPlane aTVTKPlane(aPlane);
659 myPlanes.push_back(aTVTKPlane);
662 myPrs3d->GetOffset(anOffset);
663 aTVTKPlane->myActor->SetPosition(anOffset);
665 if (PreviewCheckBox->isChecked())
666 aTVTKPlane->myActor->VisibilityOn();
669 SetCurrentPlaneParam();
673 //=================================================================================
674 // function : ClickOnDelete()
676 //=================================================================================
677 void VisuGUI_ClippingDlg::ClickOnDelete()
679 if (!myPrs3d || myPlanes.empty())
682 int aPlaneIndex = ComboBoxPlanes->currentItem();
684 VISU::TPlanes::iterator anIter = myPlanes.begin() + aPlaneIndex;
685 anIter->GetPointer()->myActor->SetVisibility(false);
686 myPlanes.erase(anIter);
688 if(AutoApplyCheckBox->isChecked())
692 if (SVTK_ViewWindow* aViewWindow = VISU::GetViewWindow(myVisuGUI))
693 VISU::RenderViewWindow(aViewWindow);
696 //=================================================================================
697 // function : onSelectOrientation()
699 //=================================================================================
700 void VisuGUI_ClippingDlg::onSelectOrientation(int theItem)
702 if (myPlanes.empty())
706 TextLabelRot1->setText(tr("LBL_ROTATION_YZ"));
707 TextLabelRot2->setText(tr("LBL_ROTATION_XZ"));
709 else if (theItem == 1) {
710 TextLabelRot1->setText(tr("LBL_ROTATION_ZX"));
711 TextLabelRot2->setText(tr("LBL_ROTATION_YX"));
713 else if (theItem == 2) {
714 TextLabelRot1->setText(tr("LBL_ROTATION_XY"));
715 TextLabelRot2->setText(tr("LBL_ROTATION_ZY"));
718 if((QComboBox*)sender() == ComboBoxOrientation)
719 SetCurrentPlaneParam();
722 //=================================================================================
723 // function : Sinchronize()
724 // purpose : update control values according to plane selection
725 //=================================================================================
726 void VisuGUI_ClippingDlg::Sinchronize()
728 int aNbPlanes = myPlanes.size();
729 ComboBoxPlanes->clear();
732 for (int i = 1; i<=aNbPlanes; i++) {
733 aName = QString(tr("PLANES_COMBO_ITEM_i")).arg(i);
734 ComboBoxPlanes->insertItem(aName);
737 int aPos = ComboBoxPlanes->count() - 1;
738 ComboBoxPlanes->setCurrentItem(aPos);
740 bool anIsControlsEnable = (aPos >= 0);
741 if (anIsControlsEnable) {
744 ComboBoxPlanes->insertItem(tr("PLANES_COMBO_ITEM_no"));
745 SpinBoxRot1->setValue(0.0);
746 SpinBoxRot2->setValue(0.0);
747 SpinBoxDistance->setValue(0.5);
750 buttonDelete ->setEnabled(anIsControlsEnable);
751 buttonApply ->setEnabled(anIsControlsEnable);
752 PreviewCheckBox ->setEnabled(anIsControlsEnable);
753 AutoApplyCheckBox ->setEnabled(anIsControlsEnable);
755 ComboBoxOrientation ->setEnabled(anIsControlsEnable);
756 SpinBoxDistance ->setEnabled(anIsControlsEnable);
757 SpinBoxRot1 ->setEnabled(anIsControlsEnable);
758 SpinBoxRot2 ->setEnabled(anIsControlsEnable);
760 ButtonGroupIJKAxis ->setEnabled(anIsControlsEnable);
761 SpinBoxIJKIndex ->setEnabled(anIsControlsEnable);
762 CheckBoxIJKPlaneReverse->setEnabled(anIsControlsEnable);
765 //=================================================================================
766 // function : setRotation()
768 //=================================================================================
769 void VisuGUI_ClippingDlg::setRotation(const double theRot1, const double theRot2)
771 SpinBoxRot1->setValue(theRot1);
772 SpinBoxRot2->setValue(theRot2);
775 //=================================================================================
776 // function : SetCurrentPlaneParam()
778 //=================================================================================
779 void VisuGUI_ClippingDlg::SetCurrentPlaneParam()
781 if (myPlanes.empty() || myIsSelectPlane)
784 int aCurPlaneIndex = ComboBoxPlanes->currentItem();
786 OrientedPlane* aPlane = myPlanes[aCurPlaneIndex].GetPointer();
789 VISU::Orientation anOrientation;
790 float aDir[3][3] = {{0, 0, 0}, {0, 0, 0}};
792 static double aCoeff = vtkMath::Pi()/180.0;
794 float aRot[2] = {getRotation1(), getRotation2()};
795 aPlane->myAngle[0] = aRot[0];
796 aPlane->myAngle[1] = aRot[1];
798 float anU[2] = {cos(aCoeff*aRot[0]), cos(aCoeff*aRot[1])};
799 float aV[2] = {sqrt(1.0-anU[0]*anU[0]), sqrt(1.0-anU[1]*anU[1])};
800 aV[0] = aRot[0] > 0? aV[0]: -aV[0];
801 aV[1] = aRot[1] > 0? aV[1]: -aV[1];
803 switch (ComboBoxOrientation->currentItem()) {
805 anOrientation = VISU::XY;
815 anOrientation = VISU::YZ;
825 anOrientation = VISU::ZX;
836 vtkMath::Cross(aDir[1],aDir[0],aNormal);
837 vtkMath::Normalize(aNormal);
838 vtkMath::Cross(aNormal,aDir[1],aDir[0]);
841 aPlane->SetOrientation(anOrientation);
842 aPlane->SetDistance(getDistance());
844 myPrs3d->SetPlaneParam(aNormal, 1. - getDistance(), aPlane);
846 vtkDataSet* aDataSet = myPrs3d->GetInput();
847 float *aPnt = aDataSet->GetCenter();
849 float* anOrigin = aPlane->GetOrigin();
850 float aDel = aDataSet->GetLength()/2.0;
852 float aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel},
853 {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}};
854 float aParam, aPnt0[3], aPnt1[3], aPnt2[3];
856 float aPnt01[3] = {aPnt[0] - aDelta[0][0] - aDelta[1][0],
857 aPnt[1] - aDelta[0][1] - aDelta[1][1],
858 aPnt[2] - aDelta[0][2] - aDelta[1][2]};
859 float aPnt02[3] = {aPnt01[0] + aNormal[0],
860 aPnt01[1] + aNormal[1],
861 aPnt01[2] + aNormal[2]};
862 vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0);
864 float aPnt11[3] = {aPnt[0] - aDelta[0][0] + aDelta[1][0],
865 aPnt[1] - aDelta[0][1] + aDelta[1][1],
866 aPnt[2] - aDelta[0][2] + aDelta[1][2]};
867 float aPnt12[3] = {aPnt11[0] + aNormal[0],
868 aPnt11[1] + aNormal[1],
869 aPnt11[2] + aNormal[2]};
870 vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1);
872 float aPnt21[3] = {aPnt[0] + aDelta[0][0] - aDelta[1][0],
873 aPnt[1] + aDelta[0][1] - aDelta[1][1],
874 aPnt[2] + aDelta[0][2] - aDelta[1][2]};
875 float aPnt22[3] = {aPnt21[0] + aNormal[0],
876 aPnt21[1] + aNormal[1],
877 aPnt21[2] + aNormal[2]};
878 vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2);
880 vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource;
881 aPlaneSource->SetNormal(aNormal[0],aNormal[1],aNormal[2]);
882 aPlaneSource->SetOrigin(aPnt0[0],aPnt0[1],aPnt0[2]);
883 aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]);
884 aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]);
886 if (AutoApplyCheckBox->isChecked())
889 if (SVTK_ViewWindow* vw = VISU::GetViewWindow(myVisuGUI))
890 VISU::RenderViewWindow(vw);
893 //=================================================================================
894 // function : onTabChanged
896 //=================================================================================
897 void VisuGUI_ClippingDlg::onTabChanged(QWidget* newTab)
899 if (newTab == WidgetIJKTab) // IJK
900 setIJKByNonStructured();
902 // set correct labels of rotation spin boxes
903 onSelectOrientation(ComboBoxOrientation->currentItem());
907 //=================================================================================
908 // function : SetCurrentPlaneIJKParam
909 // purpose : set non structured parameters by IJK parameters
910 //=================================================================================
911 void VisuGUI_ClippingDlg::SetCurrentPlaneIJKParam()
913 if (myPlanes.empty() || myIsSelectPlane || !WidgetIJKTab->isEnabled())
916 VISU::Result_i* result = myPrs3d ? myPrs3d->GetResult() : 0;
921 int i, axId = ButtonGroupIJKAxis->id (ButtonGroupIJKAxis->selected());
922 VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) axId;
924 const vector<float> * values =
925 result->GetAxisInfo(myPrs3d->GetMeshName(), axis, dir);
930 int index = SpinBoxIJKIndex->value();
932 if (index < values->size())
933 distance = (*values)[ index ];
935 // find id of axis closest to dir
939 double cos[3] = { gp::DZ() * dir, gp::DX() * dir, gp::DY() * dir };
941 for (i = 0; i < 3; ++i) {
942 if (Abs(cos[ i ]) > Abs (maxCos)) {
947 // find rotation angles
950 (axId == 0) ? 2 : axId - 1,
951 (axId == 2) ? 0 : axId + 1
953 static double aCoeff = 180.0/vtkMath::Pi();
954 for (i = 0; i < 2; ++i) {
955 float cosin = cos[ rotId[ i ]];
958 angle[ i ] = asin(cosin) * aCoeff;
960 angle[ i ] += 180. * (angle[ i ] < 0 ? 1. : -1.);
962 if (CheckBoxIJKPlaneReverse->isChecked()) {
963 angle[ 0 ] += 180. * (angle[ 0 ] < 0 ? 1. : -1.);
964 distance = 1. - distance;
967 distance = 1. - distance;
970 myIsSelectPlane = true;
971 ComboBoxOrientation->setCurrentItem(axId);
972 setRotation(-angle[0], -angle[1]);
973 setDistance(distance);
974 myIsSelectPlane = false;
976 SetCurrentPlaneParam();
979 //=================================================================================
980 // function : setIJKByNonStructured
981 // purpose : convert current non structured parameters to structured ones
982 //=================================================================================
983 void VisuGUI_ClippingDlg::setIJKByNonStructured()
985 if (!myPrs3d || myPlanes.empty() || !myPrs3d->GetResult())
989 int planeIndex = ComboBoxPlanes->currentItem();
990 OrientedPlane* plane = myPlanes[ planeIndex ].GetPointer();
991 vtkPlaneSource* planeSource = plane->myPlaneSource;
992 float * planeNormal = planeSource->GetNormal();
993 gp_Dir normal(planeNormal[0], planeNormal[1], planeNormal[2]);
995 // find a grid axis most co-directed with plane normal
996 // and cartesian axis most co-directed with plane normal
997 int i, maxAx = 0, gridAxId = 0;
1000 const vector<float> *curValues, *values = 0;
1001 VISU::Result_i* result = myPrs3d->GetResult();
1002 for (i = 0; i < 3; ++i) {
1003 VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) i;
1004 curValues = result->GetAxisInfo(myPrs3d->GetMeshName(), axis, dir);
1006 double dot = normal * dir;
1007 if (Abs(dot) > Abs(maxDot)) {
1014 if (Abs (planeNormal[ maxAx ]) < Abs (planeNormal[ i ]))
1017 gp_XYZ axDir(0,0,0);
1018 axDir.SetCoord(maxAx + 1, 1.);
1021 double v = SpinBoxDistance->value();
1023 bool reverse = (normal * axDir < 0); // normal and axis are opposite
1024 if (gridDir * axDir < 0) // grid dir and axis are opposite
1028 for (i = 0; i < values->size(); ++i)
1029 if ((*values)[ i ] > v)
1031 if (i == values->size())
1033 if (i != 0 && (*values)[ i ] - v > v - (*values)[ i - 1])
1036 // set control values
1037 myIsSelectPlane = true;
1038 CheckBoxIJKPlaneReverse->setChecked(normal * axDir < 0);
1039 SpinBoxIJKIndex->setValue(i);
1040 ButtonGroupIJKAxis->setButton(gridAxId);
1041 onIJKAxisChanged(gridAxId); // update label and range of index
1042 myIsSelectPlane = false;
1044 SetCurrentPlaneIJKParam();
1047 //=================================================================================
1048 // function : isStructured
1049 // purpose : return true if mesh is structured
1050 //=================================================================================
1051 bool VisuGUI_ClippingDlg::isStructured() const
1053 VISU::Result_i* result = myPrs3d ? myPrs3d->GetResult() : 0;
1056 return result->GetAxisInfo(myPrs3d->GetMeshName(),
1057 VISU::Result_i::AXIS_X,
1063 //=================================================================================
1064 // function : onIJKAxisChanged
1065 // purpose : update Index range and call SetCurrentPlaneParam()
1066 //=================================================================================
1067 void VisuGUI_ClippingDlg::onIJKAxisChanged(int axisId)
1071 VISU::Result_i* result = myPrs3d ? myPrs3d->GetResult() : 0;
1073 VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) axisId;
1075 const vector<float> * indices = result->GetAxisInfo(myPrs3d->GetMeshName(),
1078 maxIndex = indices->size() - 1;
1080 QString text = tr("LBL_IJK_INDEX_TO_arg").arg(maxIndex);
1081 TextLabelIJKIndex->setText(text);
1082 SpinBoxIJKIndex->setRange(0, maxIndex);
1084 if (SpinBoxIJKIndex->value() > maxIndex)
1085 SpinBoxIJKIndex->setValue(0);
1087 SetCurrentPlaneIJKParam();
1090 //=================================================================================
1091 // function : OnPreviewToggle()
1093 //=================================================================================
1094 void VisuGUI_ClippingDlg::OnPreviewToggle (bool theIsToggled)
1096 std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(theIsToggled));
1097 if (SVTK_ViewWindow* vw = VISU::GetViewWindow(myVisuGUI))
1098 VISU::RenderViewWindow(vw);