1 // Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "VisuGUI_ClippingDlg.h"
26 #include "VisuGUI_Tools.h"
27 #include "VisuGUI_ViewTools.h"
29 #include "VISU_Prs3d_i.hh"
30 #include "VISU_Result_i.hh"
31 #include "VISU_ColoredPrs3dHolder_i.hh"
33 #include "VISU_PipeLine.hxx"
34 #include "VISU_PipeLineUtils.hxx"
35 #include "VISU_DataSetActor.h"
37 #include <SalomeApp_IntSpinBox.h>
38 #include <SalomeApp_DoubleSpinBox.h>
40 #include "LightApp_SelectionMgr.h"
41 #include "LightApp_Application.h"
43 #include "SVTK_ViewWindow.h"
44 #include <VTKViewer_Utilities.h>
46 #include "SUIT_Session.h"
47 #include "SUIT_Desktop.h"
48 #include "SUIT_MessageBox.h"
49 #include "SUIT_ResourceMgr.h"
50 #include "SUIT_OverrideCursor.h"
52 #include "SALOME_Actor.h"
53 #include "VISU_ViewManager_i.hh"
61 #include <QButtonGroup>
64 #include <QRadioButton>
66 #include <QPushButton>
67 #include <QListWidget>
68 #include <QVBoxLayout>
69 #include <QHBoxLayout>
70 #include <QStackedWidget>
74 #include <vtkCamera.h>
75 #include <vtkRenderer.h>
76 #include <vtkDataSet.h>
77 #include <vtkDataSetMapper.h>
78 #include <vtkImplicitFunction.h>
79 #include <vtkPlaneSource.h>
80 #include <vtkPolyData.h>
81 #include <vtkUnstructuredGrid.h>
82 #include <vtkProperty.h>
83 #include <vtkImplicitFunctionCollection.h>
91 float GetFloat (const QString& theValue, float theDefault)
93 if (theValue.isEmpty()) return theDefault;
94 SUIT_ResourceMgr* aResourceMgr = VISU::GetResourceMgr();
95 QString aValue = aResourceMgr->stringValue("VISU",theValue);
96 if (aValue.isEmpty()) return theDefault;
97 return aValue.toFloat();
100 void RenderViewWindow (SVTK_ViewWindow* vw)
103 vw->getRenderer()->ResetCameraClippingRange();
109 //=================================================================================
110 //class : OrientedPlane
112 //=================================================================================
113 OrientedPlane* OrientedPlane::New()
115 return new OrientedPlane();
118 OrientedPlane* OrientedPlane::New (SVTK_ViewWindow* vw)
120 return new OrientedPlane(vw);
123 void OrientedPlane::SetOrientation(VISU::Orientation theOrientation)
125 myOrientation = theOrientation;
128 VISU::Orientation OrientedPlane::GetOrientation()
130 return myOrientation;
133 void OrientedPlane::SetDistance(float theDistance)
135 myDistance = theDistance;
138 float OrientedPlane::GetDistance()
143 void OrientedPlane::ShallowCopy(OrientedPlane* theOrientedPlane)
145 SetNormal(theOrientedPlane->GetNormal());
146 SetOrigin(theOrientedPlane->GetOrigin());
148 myOrientation = theOrientedPlane->GetOrientation();
149 myDistance = theOrientedPlane->GetDistance();
151 myAngle[0] = theOrientedPlane->myAngle[0];
152 myAngle[1] = theOrientedPlane->myAngle[1];
154 myPlaneSource->SetNormal(theOrientedPlane->myPlaneSource->GetNormal());
155 myPlaneSource->SetOrigin(theOrientedPlane->myPlaneSource->GetOrigin());
156 myPlaneSource->SetPoint1(theOrientedPlane->myPlaneSource->GetPoint1());
157 myPlaneSource->SetPoint2(theOrientedPlane->myPlaneSource->GetPoint2());
160 OrientedPlane::OrientedPlane(SVTK_ViewWindow* vw):
161 myOrientation(VISU::XY),
166 myViewWindow->AddActor(myActor, false, false); // don't adjust actors
169 OrientedPlane::OrientedPlane():
170 myOrientation(VISU::XY),
177 void OrientedPlane::Init()
179 myPlaneSource = vtkPlaneSource::New();
181 myAngle[0] = myAngle[1] = 0.0;
183 // Create and display actor
184 myMapper = vtkDataSetMapper::New();
185 myMapper->SetInput(myPlaneSource->GetOutput());
187 myActor = SALOME_Actor::New();
188 myActor->VisibilityOff();
189 myActor->PickableOff();
190 myActor->SetInfinitive(true);
191 myActor->SetMapper(myMapper);
193 vtkProperty* aProp = vtkProperty::New();
196 SUIT_ResourceMgr* aResourceMgr = VISU::GetResourceMgr();
198 QColor aFillColor = aResourceMgr->colorValue("SMESH", "fill_color", QColor(0, 170, 255));
199 anRGB[0] = aFillColor.red()/255.;
200 anRGB[1] = aFillColor.green()/255.;
201 anRGB[2] = aFillColor.blue()/255.;
202 aProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
203 aProp->SetOpacity(0.75);
204 myActor->SetProperty(aProp);
207 vtkProperty* aBackProp = vtkProperty::New();
208 QColor aBackFaceColor = aResourceMgr->colorValue("SMESH", "backface_color", QColor(0, 0, 255));//@
209 anRGB[0] = aBackFaceColor.red()/255.;
210 anRGB[1] = aBackFaceColor.green()/255.;
211 anRGB[2] = aBackFaceColor.blue()/255.;
212 aBackProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
213 aBackProp->SetOpacity(0.75);
214 myActor->SetBackfaceProperty(aBackProp);
218 OrientedPlane::~OrientedPlane()
220 if ( !myViewWindow.isNull() )
221 myViewWindow->RemoveActor(myActor);
225 myMapper->RemoveAllInputs();
228 // commented: porting to vtk 5.0
229 //myPlaneSource->UnRegisterAllOutputs();
230 myPlaneSource->Delete();
233 struct TSetVisiblity {
234 TSetVisiblity(int theIsVisible): myIsVisible(theIsVisible){}
235 void operator()(VISU::TVTKPlane& theOrientedPlane){
236 theOrientedPlane->myActor->SetVisibility(myIsVisible);
241 //=================================================================================
242 // class : VisuGUI_ClippingDlg()
245 //=================================================================================
246 VisuGUI_ClippingDlg::VisuGUI_ClippingDlg (VisuGUI* theModule,
248 : QDialog(VISU::GetDesktop(theModule), Qt::WindowTitleHint | Qt::WindowSystemMenuHint ),
249 mySelectionMgr(VISU::GetSelectionMgr(theModule)),
250 myVisuGUI(theModule),
252 myIsSelectPlane(false),
255 setWindowTitle(tr("TITLE"));
256 setSizeGripEnabled(TRUE);
257 setAttribute( Qt::WA_DeleteOnClose, true );
259 QVBoxLayout* VisuGUI_ClippingDlgLayout = new QVBoxLayout(this);
260 VisuGUI_ClippingDlgLayout->setSpacing(6);
261 VisuGUI_ClippingDlgLayout->setMargin(11);
263 QStackedWidget* aStackWidget = new QStackedWidget(this);
264 VisuGUI_ClippingDlgLayout->addWidget(aStackWidget);
266 QWidget* aLocalPlanes = new QWidget(aStackWidget);
267 QVBoxLayout* aLocalLayout = new QVBoxLayout(aLocalPlanes);
268 aStackWidget->addWidget(aLocalPlanes);
270 // Controls for selecting, creating, deleting planes
271 QGroupBox* GroupPlanes = new QGroupBox (tr("GRP_PLANES"), aLocalPlanes);
272 QGridLayout* GroupPlanesLayout = new QGridLayout (GroupPlanes);
273 GroupPlanesLayout->setAlignment(Qt::AlignTop);
274 GroupPlanesLayout->setSpacing(6);
275 GroupPlanesLayout->setMargin(11);
276 aLocalLayout->addWidget(GroupPlanes);
278 ComboBoxPlanes = new QComboBox (GroupPlanes);
279 GroupPlanesLayout->addWidget(ComboBoxPlanes, 0, 0);
281 QSpacerItem* spacerGP = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
282 GroupPlanesLayout->addItem(spacerGP, 0, 1);
284 buttonNew = new QPushButton (GroupPlanes );
285 buttonNew->setText(tr("BUT_NEW"));
286 GroupPlanesLayout->addWidget(buttonNew, 0, 2);
288 buttonDelete = new QPushButton(GroupPlanes);
289 buttonDelete->setText(tr("BUT_DELETE"));
290 GroupPlanesLayout->addWidget(buttonDelete, 0, 3);
292 // Controls for defining plane parameters
295 QGroupBox* GroupParameters = new QGroupBox(tr("GRP_PARAMETERS"), aLocalPlanes);
296 QGridLayout* GroupParametersLayout = new QGridLayout (GroupParameters);
297 GroupParametersLayout->setAlignment(Qt::AlignTop);
298 GroupParametersLayout->setSpacing(6);
299 GroupParametersLayout->setMargin(11);
300 aLocalLayout->addWidget(GroupParameters);
302 TabPane = new QTabWidget (GroupParameters);
303 TabPane->addTab(createParamsTab() , tr("TAB_NON_STRUCTURED"));
304 TabPane->addTab(createIJKParamsTab(), tr("TAB_IJK_STRUCTURED"));
305 GroupParametersLayout->addWidget(TabPane, 0, 0);
311 // "Show preview" and "Auto Apply" check boxes
312 QHBoxLayout* aCheckBoxLayout = new QHBoxLayout(this);
313 VisuGUI_ClippingDlgLayout->addLayout(aCheckBoxLayout);
315 PreviewCheckBox = new QCheckBox (tr("SHOW_PREVIEW_CHK"), this);
316 PreviewCheckBox->setChecked(true);
317 aCheckBoxLayout->addWidget(PreviewCheckBox);
318 aCheckBoxLayout->addStretch();
320 AutoApplyCheckBox = new QCheckBox (tr("AUTO_APPLY_CHK"), this);
321 AutoApplyCheckBox->setChecked(false);
322 aCheckBoxLayout->addWidget(AutoApplyCheckBox);
324 // Controls for "Ok", "Apply" and "Close" button
325 QGroupBox* GroupButtons = new QGroupBox (this);
326 VisuGUI_ClippingDlgLayout->addWidget(GroupButtons);
327 QSizePolicy aSizePolicy(QSizePolicy::Expanding,
328 QSizePolicy::Fixed );
329 aSizePolicy.setHeightForWidth( GroupButtons->sizePolicy().hasHeightForWidth() );
330 aSizePolicy.setHorizontalStretch( 0 );
331 aSizePolicy.setVerticalStretch( 0 );
332 GroupButtons->setSizePolicy( aSizePolicy );
333 GroupButtons->setGeometry(QRect(10, 10, 281, 48));
334 QGridLayout* GroupButtonsLayout = new QGridLayout (GroupButtons);
335 GroupButtons->setLayout(GroupButtonsLayout);
336 GroupButtonsLayout->setAlignment(Qt::AlignTop);
337 GroupButtonsLayout->setSpacing(6);
338 GroupButtonsLayout->setMargin(11);
339 buttonHelp = new QPushButton (GroupButtons);
340 buttonHelp->setText(tr("BUT_HELP"));
341 buttonHelp->setAutoDefault(TRUE);
342 GroupButtonsLayout->addWidget(buttonHelp, 0, 4);
343 buttonCancel = new QPushButton (GroupButtons);
344 buttonCancel->setText(tr("BUT_CLOSE"));
345 buttonCancel->setAutoDefault(TRUE);
346 GroupButtonsLayout->addWidget(buttonCancel, 0, 3);
347 buttonApply = new QPushButton (GroupButtons);
348 buttonApply->setText(tr("BUT_APPLY"));
349 buttonApply->setAutoDefault(TRUE);
350 GroupButtonsLayout->addWidget(buttonApply, 0, 1);
351 QSpacerItem* spacer_9 = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
352 GroupButtonsLayout->addItem(spacer_9, 0, 2);
353 buttonOk = new QPushButton (GroupButtons);
354 buttonOk->setText(tr("BUT_OK"));
355 buttonOk->setAutoDefault(TRUE);
356 buttonOk->setDefault(TRUE);
357 GroupButtonsLayout->addWidget(buttonOk, 0, 0);
360 VISU::initSpinBox( SpinBoxDistance, 0., 1., .01, "length_precision" );
361 VISU::initSpinBox( SpinBoxRot1, -180., 180., 1., "angle_precision" );
362 VISU::initSpinBox( SpinBoxRot2, -180., 180., 1., "angle_precision" );
364 ComboBoxOrientation->addItem(tr("PARALLEL_XOY_COMBO_ITEM"));
365 ComboBoxOrientation->addItem(tr("PARALLEL_YOZ_COMBO_ITEM"));
366 ComboBoxOrientation->addItem(tr("PARALLEL_ZOX_COMBO_ITEM"));
368 SpinBoxDistance->setValue(0.5);
370 onSelectionChanged();
372 // signals and slots connections :
373 connect(ComboBoxPlanes , SIGNAL(activated(int)) , this, SLOT(onSelectPlane(int)));
374 connect(buttonNew , SIGNAL(clicked()) , this, SLOT(ClickOnNew()));
375 connect(buttonDelete , SIGNAL(clicked()) , this, SLOT(ClickOnDelete()));
376 connect(ComboBoxOrientation , SIGNAL(activated(int)) , this, SLOT(onSelectOrientation(int)));
377 connect(SpinBoxDistance , SIGNAL(valueChanged(double)) , this, SLOT(SetCurrentPlaneParam()));
378 connect(SpinBoxRot1 , SIGNAL(valueChanged(double)) , this, SLOT(SetCurrentPlaneParam()));
379 connect(SpinBoxRot2 , SIGNAL(valueChanged(double)) , this, SLOT(SetCurrentPlaneParam()));
380 connect(ButtonGroupIJKAxis , SIGNAL(buttonClicked(int)) , this, SLOT(onIJKAxisChanged(int)));
381 connect(SpinBoxIJKIndex , SIGNAL(valueChanged(int)) , this, SLOT(SetCurrentPlaneIJKParam()));
382 connect(CheckBoxIJKPlaneReverse, SIGNAL(toggled(bool)) , this, SLOT(SetCurrentPlaneIJKParam()));
383 connect(TabPane , SIGNAL(currentChanged (QWidget*)), this, SLOT(onTabChanged(QWidget*)));
385 connect(PreviewCheckBox , SIGNAL(toggled(bool)), this, SLOT(OnPreviewToggle(bool)));
386 connect(AutoApplyCheckBox, SIGNAL(toggled(bool)), this, SLOT(ClickOnApply()));
388 connect(buttonOk , SIGNAL(clicked()), this, SLOT(ClickOnOk()));
389 connect(buttonApply , SIGNAL(clicked()), this, SLOT(ClickOnApply()));
390 connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()));
391 connect(buttonHelp , SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
393 connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionChanged()));
398 //=================================================================================
399 // function : ~VisuGUI_ClippingDlg()
401 //=================================================================================
402 VisuGUI_ClippingDlg::~VisuGUI_ClippingDlg()
404 // no need to delete child widgets, Qt does it all for us
406 std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
407 VISU::RenderViewWindow(VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI));
410 //=================================================================================
411 // function : createParamsTab
413 //=================================================================================
414 QWidget* VisuGUI_ClippingDlg::createParamsTab()
416 QFrame* GroupParameters = new QFrame(this);
417 QGridLayout* GroupParametersLayout = new QGridLayout(GroupParameters);
418 GroupParametersLayout->setAlignment(Qt::AlignTop);
419 GroupParametersLayout->setSpacing(6);
420 GroupParametersLayout->setMargin(11);
422 TextLabelOrientation = new QLabel(GroupParameters);
423 TextLabelOrientation->setText(tr("LBL_ORIENTATION"));
424 GroupParametersLayout->addWidget(TextLabelOrientation, 0, 0);
426 ComboBoxOrientation = new QComboBox(GroupParameters);
427 GroupParametersLayout->addWidget(ComboBoxOrientation, 0, 1);
429 TextLabelDistance = new QLabel(GroupParameters);
430 TextLabelDistance->setText(tr("LBL_DISTANCE"));
431 GroupParametersLayout->addWidget(TextLabelDistance, 1, 0);
433 SpinBoxDistance = new SalomeApp_DoubleSpinBox(GroupParameters);
434 GroupParametersLayout->addWidget(SpinBoxDistance, 1, 1);
436 TextLabelRot1 = new QLabel(GroupParameters);
437 TextLabelRot1->setText(tr("LBL_ROTATION_YZ"));
438 GroupParametersLayout->addWidget(TextLabelRot1, 2, 0);
440 SpinBoxRot1 = new SalomeApp_DoubleSpinBox(GroupParameters);
441 GroupParametersLayout->addWidget(SpinBoxRot1, 2, 1);
443 TextLabelRot2 = new QLabel(GroupParameters);
444 TextLabelRot2->setText(tr("LBL_ROTATION_XZ"));
445 GroupParametersLayout->addWidget(TextLabelRot2, 3, 0);
447 SpinBoxRot2 = new SalomeApp_DoubleSpinBox(GroupParameters);
448 GroupParametersLayout->addWidget(SpinBoxRot2, 3, 1);
450 return GroupParameters;
453 //=================================================================================
454 // function : createIJKParamsTab
456 //=================================================================================
457 QWidget* VisuGUI_ClippingDlg::createIJKParamsTab()
460 WidgetIJKTab = new QFrame(this);
461 QGridLayout* IJKParametersLayout = new QGridLayout(WidgetIJKTab);
462 IJKParametersLayout->setAlignment(Qt::AlignTop);
463 IJKParametersLayout->setSpacing(6);
464 IJKParametersLayout->setMargin(11);
467 ButtonGroupIJKAxis = new QButtonGroup ( WidgetIJKTab);
468 //QGroupBox* aGBGroupBoxIJKAxis= new QGroupBox(tr("GRP_IJK_AXIS"), WidgetIJKTab );
469 GroupBoxIJKAxis= new QGroupBox(tr("GRP_IJK_AXIS"), WidgetIJKTab );
470 QHBoxLayout* aHBLay = new QHBoxLayout( GroupBoxIJKAxis );
471 ButtonGroupIJKAxis->addButton( new QRadioButton (tr("I_RADIO_BTN"), GroupBoxIJKAxis), 0 ); // 0
472 ButtonGroupIJKAxis->addButton( new QRadioButton (tr("J_RADIO_BTN"), GroupBoxIJKAxis), 1 ); // 1
473 ButtonGroupIJKAxis->addButton( new QRadioButton (tr("K_RADIO_BTN"), GroupBoxIJKAxis), 2 ); // 2
474 ButtonGroupIJKAxis->button(0)->setChecked(true);
475 aHBLay->addWidget( ButtonGroupIJKAxis->button(0) );
476 aHBLay->addWidget( ButtonGroupIJKAxis->button(1) );
477 aHBLay->addWidget( ButtonGroupIJKAxis->button(2) );
480 TextLabelIJKIndex = new QLabel(WidgetIJKTab);
481 TextLabelIJKIndex->setText(tr("LBL_IJK_INDEX"));
482 SpinBoxIJKIndex = new SalomeApp_IntSpinBox(WidgetIJKTab);
483 SpinBoxIJKIndex->setAcceptNames( false );
486 CheckBoxIJKPlaneReverse = new QCheckBox (tr("REVERSE_NORMAL_CHK"), WidgetIJKTab);
487 CheckBoxIJKPlaneReverse->setChecked(false);
489 IJKParametersLayout->addWidget(GroupBoxIJKAxis, 0, 0, 1, 2);
490 IJKParametersLayout->addWidget(TextLabelIJKIndex, 1, 0);
491 IJKParametersLayout->addWidget(SpinBoxIJKIndex, 1, 1);
492 IJKParametersLayout->addWidget(CheckBoxIJKPlaneReverse, 2, 0);
497 //=================================================================================
498 // function : ClickOnApply()
500 //=================================================================================
501 void VisuGUI_ClippingDlg::ClickOnApply()
507 //=================================================================================
508 // function : applyLocalPlanes()
510 //=================================================================================
511 void VisuGUI_ClippingDlg::applyLocalPlanes()
516 if (SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI)) {
517 SUIT_OverrideCursor wc;
519 QWidget *aCurrWid = this->focusWidget();
520 aCurrWid->clearFocus();
521 aCurrWid->setFocus();
523 // Save clipping planes, currently applied to the presentation
524 // to enable restoring this state in case of failure.
525 // Refer to bugs IPAL8849, IPAL8850 for more information.
526 typedef vtkSmartPointer<vtkPlane> TPln;
527 typedef std::vector<TPln> TPlns;
528 bool isFailed = false;
530 int iopl = 0, nbOldPlanes = myPrs3d->GetNumberOfClippingPlanes();
531 for (; iopl < nbOldPlanes; iopl++) {
532 anOldPlanes.push_back(myPrs3d->GetClippingPlane(iopl));
535 // Try to apply new clipping
536 //myPrs3d->RemoveAllClippingPlanes();
537 removeAllClippingPlanes(myPrs3d);
539 VISU::TPlanes::iterator anIter = myPlanes.begin();
540 for (; anIter != myPlanes.end(); anIter++) {
541 OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow);
542 anOrientedPlane->ShallowCopy(anIter->GetPointer());
543 if (!myPrs3d->AddClippingPlane(anOrientedPlane)) {
546 anOrientedPlane->Delete();
549 // Check contents of the resulting (clipped) presentation data
551 VISU_PipeLine* aPL = myPrs3d->GetPipeLine();
552 vtkMapper* aMapper = aPL->GetMapper();
553 vtkDataSet* aPrsData = aMapper->GetInput();
555 if (aPrsData->GetNumberOfCells() < 1) {
561 // Restore previous clipping state because of failure.
562 //myPrs3d->RemoveAllClippingPlanes();
563 removeAllClippingPlanes(myPrs3d);
565 TPlns::iterator anOldIter = anOldPlanes.begin();
566 for (; anOldIter != anOldPlanes.end(); anOldIter++) {
567 myPrs3d->AddClippingPlane(anOldIter->GetPointer());
570 SUIT_MessageBox::warning(VISU::GetDesktop(myVisuGUI),
572 tr("WRN_EMPTY_RESULTING_PRS"),
576 //VISU::RenderViewWindow(aViewWindow);
577 VISU::RepaintViewWindows(myVisuGUI, myIO);
584 //=================================================================================
585 // function : ClickOnOk()
587 //=================================================================================
588 void VisuGUI_ClippingDlg::ClickOnOk()
594 //=================================================================================
595 // function : ClickOnCancel()
597 //=================================================================================
598 void VisuGUI_ClippingDlg::ClickOnCancel()
603 //=================================================================================
604 // function : ClickOnHelp()
606 //=================================================================================
607 void VisuGUI_ClippingDlg::ClickOnHelp()
609 QString aHelpFileName = "clipping_page.html";
610 LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
612 app->onHelpContextModule(myVisuGUI ? app->moduleName(myVisuGUI->moduleName()) : QString(""), aHelpFileName);
616 platform = "winapplication";
618 platform = "application";
620 SUIT_MessageBox::warning(0, QObject::tr("WRN_WARNING"),
621 QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
622 arg(app->resourceMgr()->stringValue("ExternalBrowser", platform)).arg(aHelpFileName),
623 QObject::tr("BUT_OK"));
627 //=================================================================================
628 // function : onSelectionChanged()
629 // purpose : Called when selection is changed
630 //=================================================================================
631 void VisuGUI_ClippingDlg::onSelectionChanged()
633 if(SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI)){
635 VISU::TSelectionInfo aSelectionInfo = VISU::GetSelectedObjects(myVisuGUI);
636 if(aSelectionInfo.empty())
639 VISU::TSelectionItem aSelectionItem = aSelectionInfo.front();
640 VISU::Base_i* aBase = aSelectionItem.myObjectInfo.myBase;
644 Handle(SALOME_InteractiveObject) anIO = aSelectionItem.myIO;
649 // rnv: fix for issue 0020114 (EDF VISU 918 : Impossible to
650 // create a new clipping plane on field presentation)
651 // set last visited presentation from holder as myPrs3d
652 VISU::ColoredPrs3dHolder_i* aHolder = dynamic_cast<VISU::ColoredPrs3dHolder_i*>(aBase);
653 VISU::Prs3d_i* aPrs3d = NULL;
655 aPrs3d = aHolder->GetPrs3dDevice();
657 aPrs3d = dynamic_cast<VISU::Prs3d_i*>(aBase);
662 std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
665 CORBA::Float anOffset[3];
666 myPrs3d->GetOffset(anOffset[0],anOffset[1],anOffset[2]);
668 vtkIdType anId = 0, anEnd = myPrs3d->GetNumberOfClippingPlanes();
669 for (; anId < anEnd; anId++) {
670 if (vtkImplicitFunction* aFunction = myPrs3d->GetClippingPlane(anId)) {
671 if (OrientedPlane* aPlane = OrientedPlane::SafeDownCast(aFunction)) {
672 OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow);
673 VISU::TVTKPlane aTVTKPlane(anOrientedPlane);
674 anOrientedPlane->Delete();
675 aTVTKPlane->ShallowCopy(aPlane);
676 aTVTKPlane->myActor->SetPosition(anOffset[0],anOffset[1],anOffset[2]);
677 myPlanes.push_back(aTVTKPlane);
682 std::for_each(myPlanes.begin(),myPlanes.end(),
683 TSetVisiblity(PreviewCheckBox->isChecked()));
686 // enable/disable IJK tab
687 TabPane->setTabEnabled(TabPane->indexOf(WidgetIJKTab), isStructured());
689 VISU::RenderViewWindow(aViewWindow);
693 //=================================================================================
694 // function : onSelectPlane()
696 //=================================================================================
697 void VisuGUI_ClippingDlg::onSelectPlane(int theIndex)
699 if (!myPrs3d || myPlanes.empty())
702 OrientedPlane* aPlane = myPlanes[theIndex].GetPointer();
705 VISU::Orientation anOrientation = aPlane->GetOrientation();
708 double aRot[2] = {aPlane->myAngle[0], aPlane->myAngle[1]};
710 // Set plane parameters in the dialog
711 myIsSelectPlane = true;
712 setDistance(aPlane->GetDistance());
713 setRotation(aRot[0], aRot[1]);
715 switch (anOrientation) {
716 case VISU::XY: item = 0; break;
717 case VISU::YZ: item = 1; break;
718 case VISU::ZX: item = 2; break;
720 ComboBoxOrientation->setCurrentIndex(item);
722 bool isIJK = (TabPane->currentWidget() == WidgetIJKTab);
724 setIJKByNonStructured();
726 onSelectOrientation(item);
728 myIsSelectPlane = false;
731 //=================================================================================
732 // function : ClickOnNew()
734 //=================================================================================
735 void VisuGUI_ClippingDlg::ClickOnNew()
737 VISU::TSelectionInfo aSelectionInfo = VISU::GetSelectedObjects(myVisuGUI);
738 if(aSelectionInfo.empty())
741 const VISU::TSelectionItem& aSelectionItem = aSelectionInfo[0];
742 if(!aSelectionItem.myObjectInfo.myBase)
745 SetCurrentPlaneParam();
750 if (SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI)) {
751 OrientedPlane* aPlane = OrientedPlane::New(aViewWindow);
752 VISU::TVTKPlane aTVTKPlane(aPlane);
753 myPlanes.push_back(aTVTKPlane);
755 CORBA::Float anOffset[3];
756 myPrs3d->GetOffset(anOffset[0],anOffset[1],anOffset[2]);
757 aTVTKPlane->myActor->SetPosition(anOffset[0],anOffset[1],anOffset[2]);
759 if (PreviewCheckBox->isChecked())
760 aTVTKPlane->myActor->VisibilityOn();
763 SetCurrentPlaneParam();
767 //=================================================================================
768 // function : ClickOnDelete()
770 //=================================================================================
771 void VisuGUI_ClippingDlg::ClickOnDelete()
773 if (!myPrs3d || myPlanes.empty())
776 int aPlaneIndex = ComboBoxPlanes->currentIndex();
778 VISU::TPlanes::iterator anIter = myPlanes.begin() + aPlaneIndex;
779 anIter->GetPointer()->myActor->SetVisibility(false);
780 myPlanes.erase(anIter);
782 if(AutoApplyCheckBox->isChecked())
786 if (SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI))
787 VISU::RenderViewWindow(aViewWindow);
790 //=================================================================================
791 // function : onSelectOrientation()
793 //=================================================================================
794 void VisuGUI_ClippingDlg::onSelectOrientation(int theItem)
796 if (myPlanes.empty())
800 TextLabelRot1->setText(tr("LBL_ROTATION_YZ"));
801 TextLabelRot2->setText(tr("LBL_ROTATION_XZ"));
803 else if (theItem == 1) {
804 TextLabelRot1->setText(tr("LBL_ROTATION_ZX"));
805 TextLabelRot2->setText(tr("LBL_ROTATION_YX"));
807 else if (theItem == 2) {
808 TextLabelRot1->setText(tr("LBL_ROTATION_XY"));
809 TextLabelRot2->setText(tr("LBL_ROTATION_ZY"));
812 if((QComboBox*)sender() == ComboBoxOrientation)
813 SetCurrentPlaneParam();
816 //=================================================================================
817 // function : Sinchronize()
818 // purpose : update control values according to plane selection
819 //=================================================================================
820 void VisuGUI_ClippingDlg::Sinchronize()
822 int aNbPlanes = myPlanes.size();
823 ComboBoxPlanes->clear();
826 for (int i = 1; i<=aNbPlanes; i++) {
827 aName = QString(tr("PLANES_COMBO_ITEM_i")).arg(i);
828 ComboBoxPlanes->addItem(aName);
831 int aPos = ComboBoxPlanes->count() - 1;
832 ComboBoxPlanes->setCurrentIndex(aPos);
834 bool anIsControlsEnable = (aPos >= 0);
835 if (anIsControlsEnable) {
838 ComboBoxPlanes->addItem(tr("PLANES_COMBO_ITEM_no"));
839 SpinBoxRot1->setValue(0.0);
840 SpinBoxRot2->setValue(0.0);
841 SpinBoxDistance->setValue(0.5);
844 buttonDelete ->setEnabled(anIsControlsEnable);
845 //buttonApply ->setEnabled(anIsControlsEnable);
846 // PreviewCheckBox ->setEnabled(anIsControlsEnable);
847 // AutoApplyCheckBox ->setEnabled(anIsControlsEnable);
849 ComboBoxOrientation ->setEnabled(anIsControlsEnable);
850 SpinBoxDistance ->setEnabled(anIsControlsEnable);
851 SpinBoxRot1 ->setEnabled(anIsControlsEnable);
852 SpinBoxRot2 ->setEnabled(anIsControlsEnable);
854 GroupBoxIJKAxis ->setEnabled(anIsControlsEnable);
855 SpinBoxIJKIndex ->setEnabled(anIsControlsEnable);
856 CheckBoxIJKPlaneReverse->setEnabled(anIsControlsEnable);
857 //ENK: 23.11.2006 - PAL13176 - EDF228 VISU : Enhancement of structured datas processing
859 VISU_PipeLine* aPipeLine = myPrs3d->GetPipeLine();
860 VISU::PIDMapper anIDMapper = aPipeLine->GetIDMapper();
861 if ( anIDMapper->IsStructured() ) {
862 VISU::TStructuredId aStructuredId = anIDMapper->GetStructure();
863 ButtonGroupIJKAxis->button(0)->setEnabled( aStructuredId[0] >= 0 );
864 ButtonGroupIJKAxis->button(1)->setEnabled( aStructuredId[1] >= 0 );
865 ButtonGroupIJKAxis->button(2)->setEnabled( aStructuredId[2] >= 0 );
871 //=================================================================================
872 // function : setRotation()
874 //=================================================================================
875 void VisuGUI_ClippingDlg::setRotation(const double theRot1, const double theRot2)
877 SpinBoxRot1->setValue(theRot1);
878 SpinBoxRot2->setValue(theRot2);
881 //=================================================================================
882 // function : SetCurrentPlaneParam()
884 //=================================================================================
885 void VisuGUI_ClippingDlg::SetCurrentPlaneParam()
887 if (myPlanes.empty() || myIsSelectPlane)
890 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
892 OrientedPlane* aPlane = myPlanes[aCurPlaneIndex].GetPointer();
894 vtkFloatingPointType aNormal[3];
895 VISU::Orientation anOrientation;
896 vtkFloatingPointType aDir[3][3] = {{0, 0, 0}, {0, 0, 0}};
898 static double aCoeff = vtkMath::Pi()/180.0;
900 vtkFloatingPointType aRot[2] = {getRotation1(), getRotation2()};
901 aPlane->myAngle[0] = aRot[0];
902 aPlane->myAngle[1] = aRot[1];
904 vtkFloatingPointType anU[2] = {cos(aCoeff*aRot[0]), cos(aCoeff*aRot[1])};
905 vtkFloatingPointType aV[2] = {sqrt(1.0-anU[0]*anU[0]), sqrt(1.0-anU[1]*anU[1])};
906 aV[0] = aRot[0] > 0? aV[0]: -aV[0];
907 aV[1] = aRot[1] > 0? aV[1]: -aV[1];
909 switch (ComboBoxOrientation->currentIndex()) {
911 anOrientation = VISU::XY;
921 anOrientation = VISU::YZ;
931 anOrientation = VISU::ZX;
942 vtkMath::Cross(aDir[1],aDir[0],aNormal);
943 vtkMath::Normalize(aNormal);
944 vtkMath::Cross(aNormal,aDir[1],aDir[0]);
947 aPlane->SetOrientation(anOrientation);
948 aPlane->SetDistance(getDistance());
950 myPrs3d->SetPlaneParam(aNormal, 1. - getDistance(), aPlane);
952 //Get bounds of the visible part of the dataset
953 vtkFloatingPointType aBounds[6];
954 myPrs3d->GetPipeLine()->GetVisibleBounds(aBounds);
957 vtkFloatingPointType aPnt[3];
958 VISU::ComputeBoxCenter(aBounds,aPnt);
960 vtkFloatingPointType* anOrigin = aPlane->GetOrigin();
962 //Get Length of the diagonal
963 vtkFloatingPointType aDel = VISU::ComputeBoxDiagonal(aBounds)/2.0;
965 vtkFloatingPointType aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel},
966 {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}};
967 vtkFloatingPointType aParam, aPnt0[3], aPnt1[3], aPnt2[3];
969 vtkFloatingPointType aPnt01[3] = {aPnt[0] - aDelta[0][0] - aDelta[1][0],
970 aPnt[1] - aDelta[0][1] - aDelta[1][1],
971 aPnt[2] - aDelta[0][2] - aDelta[1][2]};
972 vtkFloatingPointType aPnt02[3] = {aPnt01[0] + aNormal[0],
973 aPnt01[1] + aNormal[1],
974 aPnt01[2] + aNormal[2]};
975 vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0);
977 vtkFloatingPointType aPnt11[3] = {aPnt[0] - aDelta[0][0] + aDelta[1][0],
978 aPnt[1] - aDelta[0][1] + aDelta[1][1],
979 aPnt[2] - aDelta[0][2] + aDelta[1][2]};
980 vtkFloatingPointType aPnt12[3] = {aPnt11[0] + aNormal[0],
981 aPnt11[1] + aNormal[1],
982 aPnt11[2] + aNormal[2]};
983 vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1);
985 vtkFloatingPointType aPnt21[3] = {aPnt[0] + aDelta[0][0] - aDelta[1][0],
986 aPnt[1] + aDelta[0][1] - aDelta[1][1],
987 aPnt[2] + aDelta[0][2] - aDelta[1][2]};
988 vtkFloatingPointType aPnt22[3] = {aPnt21[0] + aNormal[0],
989 aPnt21[1] + aNormal[1],
990 aPnt21[2] + aNormal[2]};
991 vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2);
993 vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource;
994 aPlaneSource->SetNormal(aNormal[0],aNormal[1],aNormal[2]);
995 aPlaneSource->SetOrigin(aPnt0[0],aPnt0[1],aPnt0[2]);
996 aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]);
997 aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]);
999 if (AutoApplyCheckBox->isChecked())
1002 if (SVTK_ViewWindow* vw = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI))
1003 VISU::RenderViewWindow(vw);
1006 //=================================================================================
1007 // function : onTabChanged
1009 //=================================================================================
1010 void VisuGUI_ClippingDlg::onTabChanged(QWidget* newTab)
1012 if (newTab == WidgetIJKTab) // IJK
1013 setIJKByNonStructured();
1015 // set correct labels of rotation spin boxes
1016 onSelectOrientation(ComboBoxOrientation->currentIndex());
1020 //=================================================================================
1021 // function : SetCurrentPlaneIJKParam
1022 // purpose : set non structured parameters by IJK parameters
1023 //=================================================================================
1024 void VisuGUI_ClippingDlg::SetCurrentPlaneIJKParam()
1026 if (myPlanes.empty() || myIsSelectPlane || !WidgetIJKTab->isEnabled())
1029 VISU::Result_i* result = myPrs3d ? myPrs3d->GetCResult() : 0;
1034 int i, axId = ButtonGroupIJKAxis->id (ButtonGroupIJKAxis->checkedButton());
1035 VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) axId;
1037 CORBA::String_var aMeshName = myPrs3d->GetMeshName();
1038 const vector<vtkFloatingPointType> * values =
1039 result->GetAxisInfo(aMeshName.in(), axis, dir);
1044 int index = SpinBoxIJKIndex->value();
1045 vtkFloatingPointType distance = 0;
1046 if (index < values->size())
1047 distance = (*values)[ index ];
1049 // find id of axis closest to dir
1050 // 0 || X-Y - axis Z
1051 // 1 || Y-Z - azis X
1052 // 2 || Z-X - axiz Y
1053 double cos[3] = { gp::DZ() * dir, gp::DX() * dir, gp::DY() * dir };
1055 for (i = 0; i < 3; ++i) {
1056 if (Abs(cos[ i ]) > Abs (maxCos)) {
1061 // find rotation angles
1062 vtkFloatingPointType angle[2];
1064 (axId == 0) ? 2 : axId - 1,
1065 (axId == 2) ? 0 : axId + 1
1067 static double aCoeff = 180.0/vtkMath::Pi();
1068 for (i = 0; i < 2; ++i) {
1069 vtkFloatingPointType cosin = cos[ rotId[ i ]];
1072 angle[ i ] = asin(cosin) * aCoeff;
1074 // angle[ i ] += 180. * (angle[ i ] < 0 ? 1. : -1.);
1076 if (CheckBoxIJKPlaneReverse->isChecked()) {
1077 angle[ 0 ] += 180. * (angle[ 0 ] < 0 ? 1. : -1.);
1078 distance = 1. - distance;
1081 // distance = 1. - distance;
1084 myIsSelectPlane = true;
1085 ComboBoxOrientation->setCurrentIndex(axId);
1086 setRotation(-angle[0], -angle[1]);
1087 setDistance(distance);
1088 myIsSelectPlane = false;
1090 SetCurrentPlaneParam();
1093 //=================================================================================
1094 // function : setIJKByNonStructured
1095 // purpose : convert current non structured parameters to structured ones
1096 //=================================================================================
1097 void VisuGUI_ClippingDlg::setIJKByNonStructured()
1099 if (!myPrs3d || myPlanes.empty() || !myPrs3d->GetCResult())
1103 int planeIndex = ComboBoxPlanes->currentIndex();
1104 OrientedPlane* plane = myPlanes[ planeIndex ].GetPointer();
1105 vtkPlaneSource* planeSource = plane->myPlaneSource;
1106 vtkFloatingPointType * planeNormal = planeSource->GetNormal();
1107 gp_Dir normal(planeNormal[0], planeNormal[1], planeNormal[2]);
1109 // find a grid axis most co-directed with plane normal
1110 // and cartesian axis most co-directed with plane normal
1111 int i, maxAx = 0, gridAxId = 0;
1112 gp_Dir dir, gridDir;
1114 const vector<vtkFloatingPointType> *curValues, *values = 0;
1115 VISU::Result_i* result = myPrs3d->GetCResult();
1117 VISU_PipeLine* aPipeLine = myPrs3d->GetPipeLine();
1118 VISU::PIDMapper anIDMapper = aPipeLine->GetIDMapper();
1119 if ( anIDMapper->IsStructured() && !anIDMapper->myIsPolarType )
1120 aNbAxes = anIDMapper->GetStructureDim();
1121 for (i = 0; i < aNbAxes; ++i) {
1122 VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) i;
1123 CORBA::String_var aMeshName = myPrs3d->GetMeshName();
1124 curValues = result->GetAxisInfo(aMeshName.in(), axis, dir);
1126 double dot = normal * dir;
1127 //ENK: 23.11.2006 - PAL13176
1133 } else if (Abs(dot) >= Abs(maxDot)) {
1141 if (Abs (planeNormal[ maxAx ]) < Abs (planeNormal[ i ]))
1144 gp_XYZ axDir(0,0,0);
1145 axDir.SetCoord(maxAx + 1, 1.);
1148 double v = SpinBoxDistance->value();
1150 bool reverse = (normal * axDir < 0); // normal and axis are opposite
1151 if (gridDir * axDir < 0) // grid dir and axis are opposite
1155 for (i = 0; i < values->size(); ++i)
1156 if ((*values)[ i ] > v)
1158 if (i == values->size())
1160 if (i != 0 && (*values)[ i ] - v > v - (*values)[ i - 1])
1163 // set control values
1164 onIJKAxisChanged(gridAxId); // first of all update label and range of index
1165 myIsSelectPlane = true;
1166 CheckBoxIJKPlaneReverse->setChecked(normal * axDir < 0);
1167 SpinBoxIJKIndex->setValue(i);
1168 ButtonGroupIJKAxis->button(gridAxId)->setChecked( true );
1169 myIsSelectPlane = false;
1171 SetCurrentPlaneIJKParam();
1174 //=================================================================================
1175 // function : isStructured
1176 // purpose : return true if mesh is structured
1177 //=================================================================================
1178 bool VisuGUI_ClippingDlg::isStructured() const
1180 VISU::Result_i* result = myPrs3d ? myPrs3d->GetCResult() : 0;
1183 return result->GetAxisInfo(myPrs3d->GetCMeshName(),
1184 VISU::Result_i::AXIS_X,
1190 //=================================================================================
1191 // function : onIJKAxisChanged
1192 // purpose : update Index range and call SetCurrentPlaneParam()
1193 //=================================================================================
1194 void VisuGUI_ClippingDlg::onIJKAxisChanged(int axisId)
1198 VISU::Result_i* result = myPrs3d ? myPrs3d->GetCResult() : 0;
1200 VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) axisId;
1202 CORBA::String_var aMeshName = myPrs3d->GetMeshName();
1203 const vector<vtkFloatingPointType> * indices = result->GetAxisInfo(aMeshName.in(),
1206 maxIndex = indices->size() - 1;
1208 QString text = tr("LBL_IJK_INDEX_TO_arg").arg(maxIndex);
1209 TextLabelIJKIndex->setText(text);
1210 SpinBoxIJKIndex->setRange(0, maxIndex);
1212 if (SpinBoxIJKIndex->value() > maxIndex)
1213 SpinBoxIJKIndex->setValue(0);
1215 SetCurrentPlaneIJKParam();
1218 //=================================================================================
1219 // function : OnPreviewToggle()
1221 //=================================================================================
1222 void VisuGUI_ClippingDlg::OnPreviewToggle (bool theIsToggled)
1224 std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(theIsToggled));
1225 if (SVTK_ViewWindow* vw = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myVisuGUI))
1226 VISU::RenderViewWindow(vw);
1230 //=================================================================================
1231 // function : keyPressEvent()
1233 //=================================================================================
1234 void VisuGUI_ClippingDlg::keyPressEvent( QKeyEvent* e )
1236 QDialog::keyPressEvent( e );
1237 if ( e->isAccepted() )
1240 if ( e->key() == Qt::Key_F1 )
1247 void VisuGUI_ClippingDlg::SetPrs3d(VISU::Prs3d_i* thePrs)
1249 if(thePrs != myPrs3d){
1251 myPrs3d->UnRegister();
1260 void VisuGUI_ClippingDlg::removeAllClippingPlanes(VISU::Prs3d_i* thePrs)
1262 for (int i = thePrs->GetNumberOfClippingPlanes() - 1; i >= 0 ; i--) {
1263 OrientedPlane* aPlane = dynamic_cast<OrientedPlane*>(thePrs->GetClippingPlane(i));
1265 thePrs->RemoveClippingPlane(i);