1 // Copyright (C) 2007-2013 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 // SMESH SMESHGUI : GUI for SMESH component
24 // File : SMESHGUI_ClippingDlg.cxx
25 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
28 #include "SMESHGUI_ClippingDlg.h"
31 #include "SMESHGUI_Utils.h"
32 #include "SMESHGUI_VTKUtils.h"
33 #include "SMESHGUI_SpinBox.h"
35 #include <SMESH_Actor.h>
36 #include <SMESH_ActorUtils.h>
38 // SALOME GUI includes
39 #include <SUIT_Desktop.h>
40 #include <SUIT_Session.h>
41 #include <SUIT_OverrideCursor.h>
42 #include <SUIT_MessageBox.h>
43 #include <SUIT_ResourceMgr.h>
44 #include <SUIT_ViewManager.h>
46 #include <SALOME_ListIO.hxx>
48 #include <SalomeApp_Study.h>
50 #include <LightApp_Application.h>
52 #include <VTKViewer_Algorithm.h>
54 #include <SVTK_ViewWindow.h>
55 #include <SVTK_RenderWindowInteractor.h>
59 #include <QPushButton>
62 #include <QVBoxLayout>
63 #include <QHBoxLayout>
64 #include <QGridLayout>
67 #include <QListWidget>
68 #include <QStackedLayout>
74 #include <vtkDataSet.h>
75 #include <vtkDataSetMapper.h>
76 #include <vtkPlaneSource.h>
77 #include <vtkProperty.h>
78 #include <vtkRenderer.h>
79 #include <vtkCallbackCommand.h>
80 #include <vtkImplicitPlaneWidget.h>
86 #define SIZEFACTOR 1.1
89 Create new object of class OrientedPlane
91 SMESH::OrientedPlane* SMESH::OrientedPlane::New()
93 return new OrientedPlane();
97 Create new object of class OrientedPlane
99 SMESH::OrientedPlane* SMESH::OrientedPlane::New( SVTK_ViewWindow* theViewWindow )
101 return new OrientedPlane( theViewWindow );
105 Copy the object of class OrientedPlane
107 void SMESH::OrientedPlane::ShallowCopy( SMESH::OrientedPlane* theOrientedPlane )
109 SetNormal( theOrientedPlane->GetNormal() );
110 SetOrigin( theOrientedPlane->GetOrigin() );
112 myRelativeOrientation = theOrientedPlane->GetOrientation();
113 myDistance = theOrientedPlane->GetDistance();
115 IsOpenGLClipping = theOrientedPlane->IsOpenGLClipping;
117 myAngle[0] = theOrientedPlane->myAngle[0];
118 myAngle[1] = theOrientedPlane->myAngle[1];
120 myAbsoluteOrientation = theOrientedPlane->myAbsoluteOrientation;
121 X = theOrientedPlane->X;
122 Y = theOrientedPlane->Y;
123 Z = theOrientedPlane->Z;
124 Dx = theOrientedPlane->Dx;
125 Dy = theOrientedPlane->Dy;
126 Dz = theOrientedPlane->Dz;
128 PlaneMode = theOrientedPlane->PlaneMode;
130 myPlaneSource->SetNormal( theOrientedPlane->myPlaneSource->GetNormal() );
131 myPlaneSource->SetOrigin( theOrientedPlane->myPlaneSource->GetOrigin() );
132 myPlaneSource->SetPoint1( theOrientedPlane->myPlaneSource->GetPoint1() );
133 myPlaneSource->SetPoint2( theOrientedPlane->myPlaneSource->GetPoint2() );
134 myPlaneSource->Update();
138 Invert current clipping plane in contrary direction
140 SMESH::OrientedPlane* SMESH::OrientedPlane::InvertPlane()
142 OrientedPlane* aPlane = new OrientedPlane();
143 aPlane->ShallowCopy( this );
144 double* aNormal = aPlane->GetNormal();
145 for( int i=0; i<3; i++ )
146 aNormal[i] = -aNormal[i];
147 aPlane->SetNormal( aNormal );
152 Constructor of class OrientedPlane
154 SMESH::OrientedPlane::OrientedPlane(SVTK_ViewWindow* theViewWindow):
155 myViewWindow(theViewWindow)
158 myViewWindow->AddActor(myActor, false, false); // don't adjust actors
162 Constructor of class OrientedPlane
164 SMESH::OrientedPlane::OrientedPlane():
171 Initialize parameters of class OrientedPlane
173 void SMESH::OrientedPlane::Init()
175 myPlaneSource = vtkPlaneSource::New();
177 PlaneMode = SMESH::Absolute;
180 myAbsoluteOrientation = 0; // CUSTOM
181 myRelativeOrientation = SMESH::XY;
183 myAngle[0] = myAngle[1] = 0.0;
185 IsOpenGLClipping = false;
187 // Create and display actor
188 myMapper = vtkDataSetMapper::New();
189 myMapper->SetInputConnection(myPlaneSource->GetOutputPort());
191 myActor = SALOME_Actor::New();
192 myActor->VisibilityOff();
193 myActor->PickableOff();
194 myActor->SetInfinitive(true);
195 myActor->SetMapper(myMapper);
199 SMESH::GetColor( "SMESH", "fill_color", ffc, delta, "255, 170, 0|-100" ) ;
201 vtkProperty* aProp = vtkProperty::New();
202 SMESH::GetColor( "SMESH", "fill_color", ffc, delta, "255, 170, 0|-100" ) ;
203 aProp->SetColor(ffc.red() / 255. , ffc.green() / 255. , ffc.blue() / 255.);
204 aProp->SetOpacity(0.75);
205 myActor->SetProperty(aProp);
208 vtkProperty* aBackProp = vtkProperty::New();
209 bfc = Qtx::mainColorToSecondary(ffc, delta);
210 aBackProp->SetColor( bfc.red() / 255. , bfc.green() / 255. , bfc.blue() / 255.);
211 aBackProp->SetOpacity(0.75);
212 myActor->SetBackfaceProperty(aBackProp);
217 Destructor of class OrientedPlane
219 SMESH::OrientedPlane::~OrientedPlane()
222 myViewWindow->RemoveActor(myActor);
225 myMapper->RemoveAllInputs();
228 // commented: porting to vtk 5.0
229 // myPlaneSource->UnRegisterAllOutputs();
230 myPlaneSource->Delete();
234 Definition of class ActorItem
236 class ActorItem : public QListWidgetItem
239 ActorItem( SMESH_Actor* theActor, const QString& theName, QListWidget* theListWidget ) :
240 QListWidgetItem( theName, theListWidget ),
241 myActor( theActor ) {}
243 SMESH_Actor* getActor() const { return myActor; }
246 SMESH_Actor* myActor;
250 Definition of class TSetVisibility
252 struct TSetVisibility {
253 // Set visibility of cutting plane
254 TSetVisibility(int theIsVisible): myIsVisible(theIsVisible){}
255 void operator()(SMESH::TPlaneData& thePlaneData){
256 bool anIsEmpty = thePlaneData.ActorList.empty();
257 thePlaneData.Plane.GetPointer()->myActor->SetVisibility(myIsVisible && !anIsEmpty);
262 /*********************************************************************************
263 ********************* class SMESHGUI_ClippingDlg *********************
264 *********************************************************************************/
269 SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule, SVTK_ViewWindow* theViewWindow ):
270 QDialog( SMESH::GetDesktop(theModule) ),
271 mySMESHGUI(theModule),
272 myViewWindow(theViewWindow)
275 setAttribute( Qt::WA_DeleteOnClose, true );
276 setWindowTitle(tr("SMESH_CLIPPING_TITLE"));
277 setSizeGripEnabled(true);
279 myPreviewWidget = vtkImplicitPlaneWidget::New();
280 myCallback = vtkCallbackCommand::New();
281 myCallback->SetClientData( this );
282 myCallback->SetCallback( SMESHGUI_ClippingDlg::ProcessEvents );
283 myPreviewWidget = createPreviewWidget();
285 myIsPreviewMoved = false;
287 QVBoxLayout* SMESHGUI_ClippingDlgLayout = new QVBoxLayout(this);
288 SMESHGUI_ClippingDlgLayout->setSpacing(SPACING);
289 SMESHGUI_ClippingDlgLayout->setMargin(MARGIN);
291 // Controls for selecting, creating, deleting planes
292 QGroupBox* GroupPlanes = new QGroupBox(tr("CLIP_PLANES"), this);
293 QGridLayout* GroupPlanesLayout = new QGridLayout(GroupPlanes);
294 GroupPlanesLayout->setSpacing(SPACING);
295 GroupPlanesLayout->setMargin(MARGIN);
297 ComboBoxPlanes = new QComboBox(GroupPlanes);
299 isOpenGLClipping = new QCheckBox( GroupPlanes );
300 isOpenGLClipping->setText( tr( "IS_OPENGL_CLIPPING" ) );
302 buttonNew = new QPushButton(tr("SMESH_BUT_NEW"), GroupPlanes);
304 MenuMode = new QMenu( "MenuMode", buttonNew );
305 MenuMode->addAction( tr( "ABSOLUTE" ), this, SLOT( onModeAbsolute() ) );
306 MenuMode->addAction( tr( "RELATIVE" ), this, SLOT( onModeRelative() ) );
307 buttonNew->setMenu( MenuMode );
308 CurrentMode = SMESH::Absolute;
310 buttonDelete = new QPushButton(tr("SMESH_BUT_DELETE"), GroupPlanes);
312 QLabel* aLabel = new QLabel(tr("MESHES_SUBMESHES_GROUPS"), GroupPlanes);
314 ActorList = new QListWidget(GroupPlanes);
315 ActorList->setSelectionMode(QAbstractItemView::SingleSelection);
317 SelectAllCheckBox = new QCheckBox(tr("SELECT_ALL"), GroupPlanes);
319 GroupPlanesLayout->addWidget(ComboBoxPlanes, 0, 0);
320 GroupPlanesLayout->addWidget(isOpenGLClipping, 0, 1);
321 GroupPlanesLayout->addWidget(new QWidget(), 0, 2);
322 GroupPlanesLayout->addWidget(buttonNew, 0, 3);
323 GroupPlanesLayout->addWidget(buttonDelete, 0, 4);
324 GroupPlanesLayout->addWidget(aLabel, 1, 0, 1, 5);
325 GroupPlanesLayout->addWidget(ActorList, 2, 0, 1, 5);
326 GroupPlanesLayout->addWidget(SelectAllCheckBox, 3, 0, 1, 5);
327 GroupPlanesLayout->setColumnStretch( 1, 1 );
329 ModeStackedLayout = new QStackedLayout();
331 // Controls for defining plane parameters
332 /********************** Mode Absolute **********************/
333 /* Controls for absolute mode of clipping plane:
334 X, Y, Z - coordinates of the intersection of cutting plane and the three axes
335 Dx, Dy, Dz - components of normal to the cutting plane
336 Orientation - direction of cutting plane
338 const double min = -1e+7;
339 const double max = 1e+7;
340 const double step = 5;
341 const int precision = -7;
344 QGroupBox* GroupAbsolutePoint = new QGroupBox( this );
345 GroupAbsolutePoint->setObjectName( "GroupPoint" );
346 GroupAbsolutePoint->setTitle( tr("BASE_POINT") );
347 QGridLayout* GroupPointLayout = new QGridLayout( GroupAbsolutePoint );
348 GroupPointLayout->setAlignment( Qt::AlignTop );
349 GroupPointLayout->setSpacing( 6 ); GroupPointLayout->setMargin( 11 );
351 TextLabelX = new QLabel( GroupAbsolutePoint );
352 TextLabelX->setObjectName( "TextLabelX" );
353 TextLabelX->setText( tr("X:") );
354 GroupPointLayout->addWidget( TextLabelX, 0, 0 );
356 SpinBox_X = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );
357 SpinBox_X->setObjectName("SpinBox_X" );
358 SpinBox_X->setPrecision( precision );
359 GroupPointLayout->addWidget( SpinBox_X, 0, 1 );
361 TextLabelY = new QLabel( GroupAbsolutePoint );
362 TextLabelY->setObjectName( "TextLabelY" );
363 TextLabelY->setText( tr("Y:") );
364 GroupPointLayout->addWidget( TextLabelY, 0, 2 );
366 SpinBox_Y = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );
367 SpinBox_Y->setObjectName("SpinBox_Y" );
368 SpinBox_Y->setPrecision( precision );
369 GroupPointLayout->addWidget( SpinBox_Y, 0, 3 );
371 TextLabelZ = new QLabel( GroupAbsolutePoint );
372 TextLabelZ->setObjectName( "TextLabelZ" );
373 TextLabelZ->setText( tr("Z:") );
374 GroupPointLayout->addWidget( TextLabelZ, 0, 4 );
376 SpinBox_Z = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );
377 SpinBox_Z->setObjectName("SpinBox_Z" );
378 SpinBox_Z->setPrecision( precision );
379 GroupPointLayout->addWidget( SpinBox_Z, 0, 5 );
381 resetButton = new QPushButton( GroupAbsolutePoint );
382 resetButton->setObjectName( "resetButton" );
383 resetButton->setText( tr( "RESET" ) );
384 GroupPointLayout->addWidget( resetButton, 0, 6 );
387 GroupAbsoluteDirection = new QGroupBox( this );
388 GroupAbsoluteDirection->setObjectName( "GroupDirection" );
389 GroupAbsoluteDirection->setTitle( tr("DIRECTION") );
390 QGridLayout* GroupDirectionLayout = new QGridLayout( GroupAbsoluteDirection );
391 GroupDirectionLayout->setAlignment( Qt::AlignTop );
392 GroupDirectionLayout->setSpacing( 6 );
393 GroupDirectionLayout->setMargin( 11 );
395 TextLabelDx = new QLabel( GroupAbsoluteDirection );
396 TextLabelDx->setObjectName( "TextLabelDx" );
397 TextLabelDx->setText( tr("Dx:") );
398 GroupDirectionLayout->addWidget( TextLabelDx, 0, 0 );
400 SpinBox_Dx = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );
401 SpinBox_Dx->setObjectName("SpinBox_Dx" );
402 SpinBox_Dx->setPrecision( precision );
403 GroupDirectionLayout->addWidget( SpinBox_Dx, 0, 1 );
405 TextLabelDy = new QLabel( GroupAbsoluteDirection );
406 TextLabelDy->setObjectName( "TextLabelDy" );
407 TextLabelDy->setText( tr("Dy:") );
408 GroupDirectionLayout->addWidget( TextLabelDy, 0, 2 );
410 SpinBox_Dy = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );
411 SpinBox_Dy->setObjectName("SpinBox_Dy" );
412 SpinBox_Dy->setPrecision( precision );
413 GroupDirectionLayout->addWidget( SpinBox_Dy, 0, 3 );
415 TextLabelDz = new QLabel( GroupAbsoluteDirection );
416 TextLabelDz->setObjectName( "TextLabelDz" );
417 TextLabelDz->setText( tr("Dz:") );
418 GroupDirectionLayout->addWidget( TextLabelDz, 0, 4 );
420 SpinBox_Dz = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );
421 SpinBox_Dz->setObjectName("SpinBox_Dz" );
422 SpinBox_Dz->setPrecision( precision );
423 GroupDirectionLayout->addWidget( SpinBox_Dz, 0, 5 );
425 invertButton = new QPushButton( GroupAbsoluteDirection );
426 invertButton->setObjectName( "invertButton" );
427 invertButton->setText( tr( "INVERT" ) );
428 GroupDirectionLayout->addWidget( invertButton, 0, 6 );
430 CBAbsoluteOrientation = new QComboBox( GroupAbsoluteDirection );
431 CBAbsoluteOrientation->setObjectName( "AbsoluteOrientation" );
432 CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "CUSTOM" ) );
433 CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||X-Y" ) );
434 CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||Y-Z" ) );
435 CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||Z-X" ) );
436 GroupDirectionLayout->addWidget( CBAbsoluteOrientation, 1, 0, 1, 6 );
438 QVBoxLayout* ModeActiveLayout = new QVBoxLayout();
439 ModeActiveLayout->setMargin( 11 ); ModeActiveLayout->setSpacing( 6 );
440 ModeActiveLayout->addWidget( GroupAbsolutePoint );
441 ModeActiveLayout->addWidget( GroupAbsoluteDirection );
443 QWidget* ModeActiveWidget = new QWidget( this );
444 ModeActiveWidget->setLayout( ModeActiveLayout );
446 /********************** Mode Relative **********************/
447 /* Controls for relative mode of clipping plane:
448 Distance - Value from 0 to 1.
449 Specifies the distance from the minimum value in a given direction of bounding box to the current position
450 Rotation1, Rotation2 - turn angles of cutting plane in given directions
451 Orientation - direction of cutting plane
453 QGroupBox* GroupParameters = new QGroupBox( tr("SMESH_PARAMETERS"), this );
454 QGridLayout* GroupParametersLayout = new QGridLayout( GroupParameters );
455 GroupParametersLayout->setMargin( 11 ); GroupParametersLayout->setSpacing( 6 );
457 TextLabelOrientation = new QLabel( tr("SMESH_ORIENTATION"), GroupParameters);
458 TextLabelOrientation->setObjectName( "TextLabelOrientation" );
459 GroupParametersLayout->addWidget( TextLabelOrientation, 0, 0 );
461 CBRelativeOrientation = new QComboBox(GroupParameters);
462 CBRelativeOrientation->setObjectName( "RelativeOrientation" );
463 CBRelativeOrientation->addItem( tr("ALONG_XY") );
464 CBRelativeOrientation->addItem( tr("ALONG_YZ") );
465 CBRelativeOrientation->addItem( tr("ALONG_ZX") );
466 GroupParametersLayout->addWidget( CBRelativeOrientation, 0, 1 );
468 TLValueDistance = new QLabel( GroupParameters );
469 TLValueDistance->setObjectName( "TLValueDistance" );
470 TLValueDistance->setAlignment( Qt::AlignCenter );
471 TLValueDistance->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
472 QFont fnt = TLValueDistance->font(); fnt.setBold( true ); TLValueDistance->setFont( fnt );
473 GroupParametersLayout->addWidget( TLValueDistance, 1, 1 );
475 TextLabelDistance = new QLabel( tr("SMESH_DISTANCE"), GroupParameters );
476 TextLabelDistance->setObjectName( "TextLabelDistance" );
477 GroupParametersLayout->addWidget( TextLabelDistance, 2, 0 );
479 SliderDistance = new QSlider( Qt::Horizontal, GroupParameters );
480 SliderDistance->setObjectName( "SliderDistance" );
481 SliderDistance->setFocusPolicy( Qt::NoFocus );
482 SliderDistance->setMinimumSize( 300, 0 );
483 SliderDistance->setMinimum( 0 );
484 SliderDistance->setMaximum( 100 );
485 SliderDistance->setSingleStep( 1 );
486 SliderDistance->setPageStep( 10 );
487 SliderDistance->setTracking( false );
488 GroupParametersLayout->addWidget( SliderDistance, 2, 1 );
490 TLValueRotation1 = new QLabel( GroupParameters );
491 TLValueRotation1->setObjectName( "TLValueRotation1" );
492 TLValueRotation1->setAlignment( Qt::AlignCenter );
493 TLValueRotation1->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
494 TLValueRotation1->setFont( fnt );
495 GroupParametersLayout->addWidget( TLValueRotation1, 3, 1 );
497 TextLabelRotation1 = new QLabel( tr("ROTATION_AROUND_X_Y2Z"), GroupParameters );
498 TextLabelRotation1->setObjectName( "TextLabelRotation1" );
499 GroupParametersLayout->addWidget( TextLabelRotation1, 4, 0 );
501 SliderRotation1 = new QSlider( Qt::Horizontal, GroupParameters );
502 SliderRotation1->setObjectName( "SliderRotation1" );
503 SliderRotation1->setFocusPolicy( Qt::NoFocus );
504 SliderRotation1->setMinimumSize( 300, 0 );
505 SliderRotation1->setMinimum( -180 );
506 SliderRotation1->setMaximum( 180 );
507 SliderRotation1->setSingleStep( 1 );
508 SliderRotation1->setPageStep( 10 );
509 SliderRotation1->setTracking(false);
510 GroupParametersLayout->addWidget( SliderRotation1, 4, 1 );
512 TLValueRotation2 = new QLabel( GroupParameters );
513 TLValueRotation2->setObjectName( "TLValueRotation2" );
514 TLValueRotation2->setAlignment( Qt::AlignCenter );
515 TLValueRotation2->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
516 TLValueRotation2->setFont( fnt );
517 GroupParametersLayout->addWidget( TLValueRotation2, 5, 1 );
519 TextLabelRotation2 = new QLabel(tr("ROTATION_AROUND_Y_X2Z"), GroupParameters);
520 TextLabelRotation2->setObjectName( "TextLabelRotation2" );
521 TextLabelRotation2->setObjectName( "TextLabelRotation2" );
522 GroupParametersLayout->addWidget( TextLabelRotation2, 6, 0 );
524 SliderRotation2 = new QSlider( Qt::Horizontal, GroupParameters );
525 SliderRotation2->setObjectName( "SliderRotation2" );
526 SliderRotation2->setFocusPolicy( Qt::NoFocus );
527 SliderRotation2->setMinimumSize( 300, 0 );
528 SliderRotation2->setMinimum( -180 );
529 SliderRotation2->setMaximum( 180 );
530 SliderRotation2->setSingleStep( 1 );
531 SliderRotation2->setPageStep( 10 );
532 SliderRotation2->setTracking(false);
533 GroupParametersLayout->addWidget( SliderRotation2, 6, 1 );
535 /***************************************************************/
536 QWidget* CheckBoxWidget = new QWidget( this );
537 QHBoxLayout* CheckBoxLayout = new QHBoxLayout( CheckBoxWidget );
539 PreviewCheckBox = new QCheckBox( tr("SHOW_PREVIEW"), CheckBoxWidget );
540 PreviewCheckBox->setObjectName( "PreviewCheckBox" );
541 PreviewCheckBox->setChecked( true );
542 CheckBoxLayout->addWidget( PreviewCheckBox, 0, Qt::AlignCenter );
544 AutoApplyCheckBox = new QCheckBox( tr("AUTO_APPLY"), CheckBoxWidget );
545 AutoApplyCheckBox->setObjectName( "AutoApplyCheckBox" );
546 CheckBoxLayout->addWidget( AutoApplyCheckBox, 0, Qt::AlignCenter );
548 /***************************************************************/
549 // Controls for "Ok", "Apply" and "Close" button
550 QGroupBox* GroupButtons = new QGroupBox(this);
551 QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons);
552 GroupButtonsLayout->setSpacing(SPACING);
553 GroupButtonsLayout->setMargin(MARGIN);
555 buttonOk = new QPushButton( tr( "SMESH_BUT_APPLY_AND_CLOSE" ), GroupButtons );
556 buttonOk->setAutoDefault( true );
557 buttonOk->setDefault( true );
558 buttonApply = new QPushButton( tr( "SMESH_BUT_APPLY" ), GroupButtons );
559 buttonApply->setAutoDefault( true );
560 buttonCancel = new QPushButton( tr( "SMESH_BUT_CLOSE" ), GroupButtons );
561 buttonCancel->setAutoDefault( true );
562 buttonHelp = new QPushButton( tr( "SMESH_BUT_HELP" ), GroupButtons );
563 buttonHelp->setAutoDefault( true );
564 GroupButtonsLayout->addWidget( buttonOk );
565 GroupButtonsLayout->addSpacing(10);
566 GroupButtonsLayout->addWidget( buttonApply );
567 GroupButtonsLayout->addSpacing(10);
568 GroupButtonsLayout->addStretch();
569 GroupButtonsLayout->addWidget( buttonCancel );
570 GroupButtonsLayout->addWidget( buttonHelp );
572 ModeStackedLayout->addWidget( ModeActiveWidget );
573 ModeStackedLayout->addWidget( GroupParameters );
575 SMESHGUI_ClippingDlgLayout->addWidget( GroupPlanes );
576 SMESHGUI_ClippingDlgLayout->addLayout( ModeStackedLayout );
577 SMESHGUI_ClippingDlgLayout->addWidget( CheckBoxWidget );
578 SMESHGUI_ClippingDlgLayout->addWidget( GroupButtons );
583 myIsSelectPlane = false;
585 myHelpFileName = "clipping_page.html";
587 // signals and slots connections :
588 connect( ComboBoxPlanes, SIGNAL( activated( int ) ), this, SLOT( onSelectPlane( int ) ) );
589 connect( isOpenGLClipping, SIGNAL( toggled( bool ) ), this, SLOT( onIsOpenGLClipping( bool ) ) );
590 connect( buttonNew, SIGNAL( clicked() ), buttonNew, SLOT( showMenu() ) );
591 connect( buttonDelete, SIGNAL( clicked() ), this, SLOT( ClickOnDelete() ) );
592 connect( ActorList, SIGNAL( itemChanged( QListWidgetItem* ) ), this, SLOT( onActorItemChanged( QListWidgetItem*) ) );
593 connect( SelectAllCheckBox, SIGNAL( stateChanged( int ) ), this, SLOT( onSelectAll( int ) ) );
595 connect( invertButton, SIGNAL (clicked() ), this, SLOT( onInvert() ) ) ;
596 connect( resetButton, SIGNAL (clicked() ), this, SLOT( onReset() ) );
597 connect( SpinBox_X, SIGNAL ( valueChanged( double ) ), this, SLOT( SetCurrentPlaneParam() ) );
598 connect( SpinBox_Y, SIGNAL ( valueChanged( double ) ), this, SLOT( SetCurrentPlaneParam() ) );
599 connect( SpinBox_Z, SIGNAL ( valueChanged( double ) ), this, SLOT( SetCurrentPlaneParam() ) );
600 connect( SpinBox_Dx, SIGNAL ( valueChanged( double ) ), this, SLOT( SetCurrentPlaneParam() ) );
601 connect( SpinBox_Dy, SIGNAL ( valueChanged( double ) ), this, SLOT( SetCurrentPlaneParam() ) );
602 connect( SpinBox_Dz, SIGNAL ( valueChanged( double ) ), this, SLOT( SetCurrentPlaneParam() ) );
603 connect( CBAbsoluteOrientation, SIGNAL ( activated ( int ) ), this, SLOT( onSelectAbsoluteOrientation( int ) ) ) ;
605 connect( CBRelativeOrientation, SIGNAL( activated( int ) ), this, SLOT( onSelectRelativeOrientation( int ) ) );
606 connect( SliderDistance, SIGNAL( sliderMoved( int ) ), this, SLOT( SliderDistanceHasMoved( int ) ) );
607 connect( SliderDistance, SIGNAL( valueChanged( int ) ), this, SLOT( SliderDistanceHasMoved( int ) ) );
608 connect( SliderRotation1, SIGNAL( sliderMoved( int ) ), this, SLOT( SliderRotation1HasMoved( int ) ) );
609 connect( SliderRotation1, SIGNAL( valueChanged( int ) ), this, SLOT( SliderRotation1HasMoved( int ) ) );
610 connect( SliderRotation2, SIGNAL( sliderMoved( int ) ), this, SLOT( SliderRotation2HasMoved( int ) ) );
611 connect( SliderRotation2, SIGNAL( valueChanged( int ) ), this, SLOT( SliderRotation2HasMoved( int ) ) );
613 connect( PreviewCheckBox, SIGNAL( toggled( bool ) ), this, SLOT( OnPreviewToggle( bool ) ) );
614 connect( AutoApplyCheckBox, SIGNAL( toggled( bool ) ), this, SLOT( onAutoApply( bool ) ) );
615 connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
616 connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( reject() ) );
617 connect( buttonApply, SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
618 connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( ClickOnHelp() ) );
619 connect( mySMESHGUI, SIGNAL ( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
620 /* to close dialog if study frame change */
621 connect( mySMESHGUI, SIGNAL ( SignalStudyFrameChanged() ), this, SLOT( reject() ) );
623 initializePlaneData();
631 Destroys the object and frees any allocated resources
633 SMESHGUI_ClippingDlg::~SMESHGUI_ClippingDlg()
635 // no need to delete child widgets, Qt does it all for us
636 std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisibility(false));
638 SMESH::RenderViewWindow(myViewWindow);
640 for( int i=0; i< myPlanes.size(); i++ ) {
641 SMESH::TPlaneData aPlaneData = myPlanes[i];
642 aPlaneData.Plane->Delete();
645 if (myPreviewWidget) {
646 myPreviewWidget->Off();
647 myPreviewWidget->Delete();
650 myCallback->Delete();
652 myViewWindow->Repaint();
656 Get distance for cutting plane in relative mode
658 double SMESHGUI_ClippingDlg::getDistance() const
660 return TLValueDistance->text().toDouble();
664 Set distance of cutting plane in relative mode
666 void SMESHGUI_ClippingDlg::setDistance( const double theDistance )
668 SliderDistance->setValue( theDistance*100 );
672 Get rotation1 for cutting plane in relative mode
674 double SMESHGUI_ClippingDlg::getRotation1() const
676 return TLValueRotation1->text().remove("\xB0").toInt();
680 Get rotation2 for cutting plane in relative mode
682 double SMESHGUI_ClippingDlg::getRotation2() const
684 return TLValueRotation2->text().remove("\xB0").toInt();
688 Set angles of clipping plane in relative mode
690 void SMESHGUI_ClippingDlg::setRotation (const double theRot1, const double theRot2)
692 SliderRotation1->setValue( theRot1 );
693 SliderRotation2->setValue( theRot2 );
697 Set coordinates of origin point in dialog box
699 void SMESHGUI_ClippingDlg::setOrigin( double theVal[3] )
701 int anOrientation = CBAbsoluteOrientation->currentIndex();
702 if( anOrientation == 0 || anOrientation == 2 )
703 SpinBox_X->setValue( theVal[0] );
704 if( anOrientation == 0 || anOrientation == 3 )
705 SpinBox_Y->setValue( theVal[1] );
706 if( anOrientation == 0 || anOrientation == 1 )
707 SpinBox_Z->setValue( theVal[2] );
711 Set coordinates of normal vector in dialog box
713 void SMESHGUI_ClippingDlg::setDirection( double theVal[3] )
715 int anOrientation = CBAbsoluteOrientation->currentIndex();
716 if( anOrientation == 0 ) {
717 SpinBox_Dx->setValue( theVal[0] );
718 SpinBox_Dy->setValue( theVal[1] );
719 SpinBox_Dz->setValue( theVal[2] );
724 Create a new widget for preview clipping plane
726 vtkImplicitPlaneWidget* SMESHGUI_ClippingDlg::createPreviewWidget()
728 vtkImplicitPlaneWidget* aPlaneWgt = vtkImplicitPlaneWidget::New();
730 aPlaneWgt->SetInteractor( myViewWindow->getInteractor() );
731 aPlaneWgt->SetPlaceFactor( SIZEFACTOR );
732 aPlaneWgt->ScaleEnabledOff();
733 aPlaneWgt->SetOrigin( 0, 0, 0 );
734 aPlaneWgt->SetNormal( -1, -1, -1 );
738 SMESH::GetColor( "SMESH", "fill_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) );
740 aPlaneWgt->GetPlaneProperty()->SetColor( anRGB[0],anRGB[1],anRGB[2] );
741 aPlaneWgt->GetPlaneProperty()->SetOpacity( 0.2 );;
743 aPlaneWgt->GetSelectedPlaneProperty()->SetColor( anRGB[0],anRGB[1],anRGB[2] );
744 aPlaneWgt->GetSelectedPlaneProperty()->SetOpacity( 0.2 );
745 aPlaneWgt->GetSelectedPlaneProperty()->SetLineWidth( 2.0 );
747 aPlaneWgt->AddObserver(vtkCommand::InteractionEvent, myCallback, 0.);
753 Translate two angles of plane to normal
755 void rotationToNormal ( double theRotation[2],
758 double theDir[2][3] )
760 static double aCoeff = M_PI/180.0;
762 double anU[2] = { cos( aCoeff * theRotation[0] ), cos( aCoeff * theRotation[1] ) };
763 double aV[2] = { sqrt( 1.0 - anU[0]*anU[0] ), sqrt( 1.0 - anU[1] * anU[1] ) };
764 aV[0] = theRotation[0] > 0? aV[0]: -aV[0];
765 aV[1] = theRotation[1] > 0? aV[1]: -aV[1];
767 switch ( theOrientation ) {
770 theDir[0][1] = anU[0];
771 theDir[0][2] = aV[0];
772 theDir[1][0] = anU[1];
773 theDir[1][2] = aV[1];
776 theDir[0][2] = anU[0];
777 theDir[0][0] = aV[0];
778 theDir[1][1] = anU[1];
779 theDir[1][0] = aV[1];
782 theDir[0][0] = anU[0];
783 theDir[0][1] = aV[0];
784 theDir[1][2] = anU[1];
785 theDir[1][1] = aV[1];
789 vtkMath::Cross( theDir[1], theDir[0], theNormal );
790 vtkMath::Normalize( theNormal );
791 vtkMath::Cross( theNormal, theDir[1], theDir[0] );
795 Used in SMESHGUI::restoreVisualParameters() to avoid
796 Declaration of OrientedPlane outside of SMESHGUI_ClippingDlg.cxx
798 bool SMESHGUI_ClippingDlg::AddPlane ( SMESH::TActorList theActorList,
799 SMESH::OrientedPlane* thePlane )
802 double aDir[2][3] = {{0, 0, 0}, {0, 0, 0}};
803 static double aCoeff = vtkMath::Pi()/180.0;
806 if ( thePlane->PlaneMode == SMESH::Absolute )
807 anOrientation = thePlane->myAbsoluteOrientation;
808 else if ( thePlane->PlaneMode == SMESH::Relative )
809 anOrientation = thePlane->myRelativeOrientation + 1;
811 if ( anOrientation == 0 ) {
812 // compute a direction for plane in absolute mode
813 double znam = sqrt( thePlane->Dx*thePlane->Dx + thePlane->Dy*thePlane->Dy + thePlane->Dz*thePlane->Dz );
814 double aRotation = acos( thePlane->Dy/znam )/aCoeff;
815 if ( thePlane->Dy >= 0.0 && thePlane->Dz >= 0.0 ) thePlane->myAngle[0] = 90.0 + aRotation;
816 else if ( thePlane->Dy >= 0.0 && thePlane->Dz < 0.0 ) thePlane->myAngle[0] = 90.0 - aRotation;
817 else if ( thePlane->Dy < 0.0 && thePlane->Dz >= 0.0 ) thePlane->myAngle[0] = aRotation - 90.0;
818 else if ( thePlane->Dy < 0.0 && thePlane->Dz < 0.0 ) thePlane->myAngle[0] = 270.0 - aRotation;
820 aRotation = acos( thePlane->Dx/znam )/aCoeff;
821 if ( thePlane->Dx >= 0.0 && thePlane->Dz >= 0.0 ) thePlane->myAngle[1] = 90.0 + aRotation;
822 else if ( thePlane->Dx >= 0.0 && thePlane->Dz < 0.0 ) thePlane->myAngle[1] = 90.0 - aRotation;
823 else if ( thePlane->Dx < 0.0 && thePlane->Dz >= 0.0 ) thePlane->myAngle[1] = aRotation - 90.0;
824 else if ( thePlane->Dx < 0.0 && thePlane->Dz < 0.0 ) thePlane->myAngle[1] = 270.0 - aRotation;
828 rotationToNormal( thePlane->myAngle, anOrientation, aNormal, aDir );
833 if ( thePlane->PlaneMode == SMESH::Absolute ) {
834 aNormal[0] = thePlane->Dx;
835 aNormal[1] = thePlane->Dy;
836 aNormal[2] = thePlane->Dz;
840 if( theActorList.empty() ) {
841 // to support planes with empty actor list we should create
842 // a nullified plane that will be initialized later
843 anOrigin[0] = anOrigin[1] = anOrigin[2] = 0;
844 aBounds[0] = aBounds[2] = aBounds[4] = 0;
845 aBounds[1] = aBounds[3] = aBounds[5] = 0;
849 anIsOk = SMESH::ComputeClippingPlaneParameters( theActorList,
851 thePlane->myDistance,
857 if ( thePlane->PlaneMode == SMESH::Absolute ) {
858 anOrigin[0] = thePlane->X;
859 anOrigin[1] = thePlane->Y;
860 anOrigin[2] = thePlane->Z;
862 thePlane->SetNormal( aNormal );
863 thePlane->SetOrigin( anOrigin );
866 double aPnt[3] = { ( aBounds[0] + aBounds[1] ) / 2.,
867 ( aBounds[2] + aBounds[3] ) / 2.,
868 ( aBounds[4] + aBounds[5] ) / 2. };
870 double aDel = pow( pow( aBounds[1] - aBounds[0], 2 ) +
871 pow( aBounds[3] - aBounds[2], 2 ) +
872 pow( aBounds[5] - aBounds[4], 2 ), 0.5 );
874 double aDelta[2][3] = { { aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel },
875 { aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel } };
876 double aParam, aPnt0[3], aPnt1[3], aPnt2[3];
878 double aPnt01[3] = { aPnt[0] - aDelta[0][0] - aDelta[1][0],
879 aPnt[1] - aDelta[0][1] - aDelta[1][1],
880 aPnt[2] - aDelta[0][2] - aDelta[1][2] };
881 double aPnt02[3] = { aPnt01[0] + aNormal[0],
882 aPnt01[1] + aNormal[1],
883 aPnt01[2] + aNormal[2] };
884 vtkPlane::IntersectWithLine( aPnt01, aPnt02, aNormal, anOrigin, aParam, aPnt0 );
886 double aPnt11[3] = { aPnt[0] - aDelta[0][0] + aDelta[1][0],
887 aPnt[1] - aDelta[0][1] + aDelta[1][1],
888 aPnt[2] - aDelta[0][2] + aDelta[1][2] };
889 double aPnt12[3] = { aPnt11[0] + aNormal[0],
890 aPnt11[1] + aNormal[1],
891 aPnt11[2] + aNormal[2] };
892 vtkPlane::IntersectWithLine( aPnt11, aPnt12, aNormal, anOrigin, aParam, aPnt1);
894 double aPnt21[3] = { aPnt[0] + aDelta[0][0] - aDelta[1][0],
895 aPnt[1] + aDelta[0][1] - aDelta[1][1],
896 aPnt[2] + aDelta[0][2] - aDelta[1][2] };
897 double aPnt22[3] = { aPnt21[0] + aNormal[0],
898 aPnt21[1] + aNormal[1],
899 aPnt21[2] + aNormal[2] };
900 vtkPlane::IntersectWithLine( aPnt21, aPnt22, aNormal, anOrigin, aParam, aPnt2);
902 vtkPlaneSource* aPlaneSource = thePlane->myPlaneSource;
903 aPlaneSource->SetNormal( aNormal[0], aNormal[1], aNormal[2] );
904 aPlaneSource->SetOrigin( aPnt0[0], aPnt0[1], aPnt0[2] );
905 aPlaneSource->SetPoint1( aPnt1[0], aPnt1[1], aPnt1[2] );
906 aPlaneSource->SetPoint2( aPnt2[0], aPnt2[1], aPnt2[2] );
907 aPlaneSource->Update();
909 SMESH::TActorList::iterator anIter = theActorList.begin();
910 for ( ; anIter != theActorList.end(); anIter++ )
911 if( vtkActor* aVTKActor = *anIter )
912 if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) {
913 if( thePlane->IsOpenGLClipping )
914 anActor->AddOpenGLClippingPlane( thePlane->InvertPlane() );
916 anActor->AddClippingPlane( thePlane );
923 Custom handling of events
925 void SMESHGUI_ClippingDlg::keyPressEvent( QKeyEvent* e )
927 QDialog::keyPressEvent( e );
928 if ( e->isAccepted() )
931 if ( e->key() == Qt::Key_F1 ) {
938 Handles the char preview widget activation event
940 void SMESHGUI_ClippingDlg::ProcessEvents( vtkObject* theObject,
941 unsigned long theEvent,
943 void* vtkNotUsed( theCallData ) )
945 vtkImplicitPlaneWidget* aWidget = vtkImplicitPlaneWidget::SafeDownCast( theObject );
946 if ( aWidget == NULL ) return;
947 if ( theClientData == NULL ) return;
949 SMESHGUI_ClippingDlg* aDlg = (SMESHGUI_ClippingDlg*) theClientData;
955 case vtkCommand::InteractionEvent:
956 aWidget->GetOrigin( anOrigin );
957 aWidget->GetNormal( aDir );
959 aDlg->myIsSelectPlane = true;
961 if( aDlg->CurrentMode == SMESH::Absolute ) {
962 aDlg->setOrigin( anOrigin );
963 aDlg->setDirection( aDir );
964 aDlg->myIsPreviewMoved = true;
966 else if( aDlg->CurrentMode == SMESH::Relative ) {
967 aDlg->absolutePlaneToRelative( anOrigin, aDir );
969 aDlg->myIsSelectPlane = false;
971 aDlg->SetCurrentPlaneParam();
972 aDlg->myIsPreviewMoved = false;
978 Initialize the planes's data when the dialog opened
980 void SMESHGUI_ClippingDlg::initializePlaneData()
982 const SMESHGUI_ClippingPlaneInfoMap& aClippingPlaneInfoMap = mySMESHGUI->getClippingPlaneInfoMap();
983 SMESHGUI_ClippingPlaneInfoMap::const_iterator anIter1 = aClippingPlaneInfoMap.find( myViewWindow->getViewManager() );
984 if( anIter1 != aClippingPlaneInfoMap.end() ) {
985 const SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = anIter1->second;
986 SMESHGUI_ClippingPlaneInfoList::const_iterator anIter2 = aClippingPlaneInfoList.begin();
987 for( ; anIter2 != aClippingPlaneInfoList.end(); anIter2++ ) {
988 const SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter2;
989 SMESH::OrientedPlane* anOrientedPlane = SMESH::OrientedPlane::New(myViewWindow);
990 anOrientedPlane->ShallowCopy(aClippingPlaneInfo.Plane);
991 SMESH::TPlane aTPlane( anOrientedPlane );
992 SMESH::TPlaneData aPlaneData( aTPlane, aClippingPlaneInfo.ActorList );
993 myPlanes.push_back( aPlaneData );
996 std::for_each( myPlanes.begin(),myPlanes.end(), TSetVisibility( PreviewCheckBox->isChecked() ) );
997 if( myPlanes.size() )
998 myPreviewWidget->SetEnabled( PreviewCheckBox->isChecked() );
1002 Initialization of initial values of widgets
1004 void SMESHGUI_ClippingDlg::initParam()
1006 SpinBox_X->setValue( 0.0 );
1007 SpinBox_Y->setValue( 0.0 );
1008 SpinBox_Z->setValue( 0.0 );
1010 SpinBox_Dx->setValue( 1.0 );
1011 SpinBox_Dy->setValue( 1.0 );
1012 SpinBox_Dz->setValue( 1.0 );
1014 CBAbsoluteOrientation->setCurrentIndex(0);
1016 TLValueDistance->setText( "0.5" );
1017 TLValueRotation1->setText( "0\xB0" );
1018 TLValueRotation2->setText( "0\xB0" );
1019 CBRelativeOrientation->setCurrentIndex( 0 );
1020 SliderDistance->setValue( 50 );
1021 SliderRotation1->setValue( 0 );
1022 SliderRotation2->setValue( 0 );
1026 Synchronize dialog's widgets with data
1028 void SMESHGUI_ClippingDlg::synchronize()
1030 int aNbPlanes = myPlanes.size();
1031 ComboBoxPlanes->clear();
1034 for( int i = 1; i<=aNbPlanes; i++ ) {
1035 aName = QString( tr( "PLANE_NUM" ) ).arg(i);
1036 ComboBoxPlanes->addItem( aName );
1039 int aPos = ComboBoxPlanes->count() - 1;
1040 ComboBoxPlanes->setCurrentIndex( aPos );
1042 bool anIsControlsEnable = ( aPos >= 0 );
1043 if ( anIsControlsEnable ) {
1044 onSelectPlane( aPos );
1046 if( PreviewCheckBox->isChecked() )
1047 myPreviewWidget->On();
1050 ComboBoxPlanes->addItem( tr( "NO_PLANES" ) );
1053 if( PreviewCheckBox->isChecked() )
1054 myPreviewWidget->Off();
1057 isOpenGLClipping->setEnabled( anIsControlsEnable );
1058 ActorList->setEnabled( anIsControlsEnable );
1059 SelectAllCheckBox->setEnabled( anIsControlsEnable );
1060 buttonDelete->setEnabled( anIsControlsEnable );
1061 if ( CurrentMode == SMESH::Absolute ) {
1062 SpinBox_X->setEnabled( anIsControlsEnable );
1063 SpinBox_Y->setEnabled( anIsControlsEnable );
1064 SpinBox_Z->setEnabled( anIsControlsEnable );
1065 SpinBox_Dx->setEnabled( anIsControlsEnable );
1066 SpinBox_Dy->setEnabled( anIsControlsEnable );
1067 SpinBox_Dz->setEnabled( anIsControlsEnable );
1068 CBAbsoluteOrientation->setEnabled( anIsControlsEnable );
1069 invertButton->setEnabled( anIsControlsEnable );
1070 resetButton->setEnabled( anIsControlsEnable );
1072 else if ( CurrentMode == SMESH::Relative ) {
1073 CBRelativeOrientation->setEnabled( anIsControlsEnable );
1074 SliderDistance->setEnabled( anIsControlsEnable );
1075 SliderRotation1->setEnabled( anIsControlsEnable );
1076 SliderRotation2->setEnabled( anIsControlsEnable );
1081 Update the list of actors
1083 void SMESHGUI_ClippingDlg::updateActorList()
1087 SalomeApp_Study* anAppStudy = SMESHGUI::activeStudy();
1091 _PTR(Study) aStudy = anAppStudy->studyDS();
1098 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
1099 const SMESH::TPlaneData& aPlaneData = myPlanes[ aCurPlaneIndex ];
1100 const SMESH::TActorList& anActorList = aPlaneData.ActorList;
1102 std::for_each( myPlanes.begin(),myPlanes.end(), TSetVisibility( PreviewCheckBox->isChecked() ) );
1103 aPlaneData.Plane.GetPointer()->myActor->SetVisibility( false );
1105 VTK::ActorCollectionCopy aCopy( myViewWindow->getRenderer()->GetActors() );
1106 vtkActorCollection* anAllActors = aCopy.GetActors();
1107 anAllActors->InitTraversal();
1108 while( vtkActor* aVTKActor = anAllActors->GetNextActor() ) {
1109 if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) {
1110 if( anActor->hasIO() ) {
1111 Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
1112 if( _PTR(SObject) aSObj = aStudy->FindObjectID( anIO->getEntry() ) ) {
1113 bool anIsChecked = false;
1114 SMESH::TActorList::const_iterator anIter = anActorList.begin();
1115 for ( ; anIter != anActorList.end(); anIter++ ) {
1116 if( vtkActor* aVTKActorRef = *anIter ) {
1117 if( SMESH_Actor* anActorRef = SMESH_Actor::SafeDownCast( aVTKActorRef ) ) {
1118 if( anActorRef == anActor ) {
1125 QString aName = QString( aSObj->GetName().c_str() );
1126 QListWidgetItem* anItem = new ActorItem( anActor, aName, ActorList );
1127 anItem->setCheckState( anIsChecked ? Qt::Checked : Qt::Unchecked );
1128 updateActorItem( anItem, true, false );
1136 Update an actor in actor's list
1138 void SMESHGUI_ClippingDlg::updateActorItem( QListWidgetItem* theItem,
1139 bool theUpdateSelectAll,
1140 bool theUpdateClippingPlaneMap )
1142 // update Select All check box
1143 if( theUpdateSelectAll ) {
1144 int aNbItems = ActorList->count(), aNbChecked = 0;
1145 for( int i = 0; i < aNbItems; i++ )
1146 if( QListWidgetItem* anItem = ActorList->item( i ) )
1147 if( anItem->checkState() == Qt::Checked )
1150 bool anIsBlocked = SelectAllCheckBox->blockSignals( true );
1151 SelectAllCheckBox->setCheckState( aNbChecked == aNbItems ? Qt::Checked : Qt::Unchecked);
1152 SelectAllCheckBox->blockSignals( anIsBlocked );
1155 // update clipping plane map
1156 if( theUpdateClippingPlaneMap ) {
1157 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
1158 if( ActorItem* anItem = dynamic_cast<ActorItem*>( theItem ) ) {
1159 if( SMESH_Actor* anActor = anItem->getActor() ) {
1160 SMESH::TPlaneData& aPlaneData = myPlanes[ aCurPlaneIndex ];
1161 SMESH::TActorList& anActorList = aPlaneData.ActorList;
1162 bool anIsPushed = false;
1163 SMESH::TActorList::iterator anIter = anActorList.begin();
1164 for ( ; anIter != anActorList.end(); anIter++ ) {
1165 if( anActor == *anIter ) {
1170 if( theItem->checkState() == Qt::Checked && !anIsPushed )
1171 anActorList.push_back( anActor );
1172 else if( theItem->checkState() == Qt::Unchecked && anIsPushed )
1173 anActorList.remove( anActor );
1175 SMESH::ComputeBounds( anActorList, myBounds );
1176 myPreviewWidget->PlaceWidget( myBounds[0], myBounds[1], myBounds[2],
1177 myBounds[3], myBounds[4], myBounds[5] );
1184 Get the list of current actors
1186 SMESH::TActorList SMESHGUI_ClippingDlg::getCurrentActors()
1188 SMESH::TActorList anActorList;
1189 for( int i = 0, n = ActorList->count(); i < n; i++ )
1190 if( ActorItem* anItem = dynamic_cast<ActorItem*>( ActorList->item( i ) ) )
1191 if( anItem->checkState() == Qt::Checked )
1192 if( SMESH_Actor* anActor = anItem->getActor() )
1193 anActorList.push_back( anActor );
1198 Dump the parameters of clipping planes
1200 void SMESHGUI_ClippingDlg::dumpPlaneData() const
1202 printf( "----------- Plane Data -----------\n" );
1204 SMESH::TPlaneDataVector::const_iterator anIter1 = myPlanes.begin();
1205 for ( ; anIter1 != myPlanes.end(); anIter1++, anId++ ) {
1206 SMESH::TPlaneData aPlaneData = *anIter1;
1207 SMESH::TPlane aPlane = aPlaneData.Plane;
1208 double* aNormal = aPlane->GetNormal();
1209 double* anOrigin = aPlane->GetOrigin();
1210 printf( "Plane N%d:\n", anId );
1211 printf( " Normal = ( %f, %f, %f )\n", aNormal[0], aNormal[1], aNormal[2] );
1212 printf( " Origin = ( %f, %f, %f )\n", anOrigin[0], anOrigin[1], anOrigin[2] );
1214 SMESH::TActorList anActorList = aPlaneData.ActorList;
1215 SMESH::TActorList::const_iterator anIter2 = anActorList.begin();
1216 for ( ; anIter2 != anActorList.end(); anIter2++ ) {
1217 if( vtkActor* aVTKActor = *anIter2 ) {
1218 if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) )
1219 printf( " - Actor: '%s'\n", anActor->getName() );
1222 printf( " - Actor: NULL\n");
1225 printf( "----------------------------------\n" );
1229 SLOT on close button click: rejects dialog
1231 void SMESHGUI_ClippingDlg::reject()
1233 //here we can insert actions to do at close.
1238 Set absolute mode of clipping plane
1240 void SMESHGUI_ClippingDlg::onModeAbsolute()
1242 ModeStackedLayout->setCurrentIndex(0);
1243 CurrentMode = SMESH::Absolute;
1245 SetCurrentPlaneParam();
1249 Set relative mode of clipping plane
1251 void SMESHGUI_ClippingDlg::onModeRelative()
1253 ModeStackedLayout->setCurrentIndex(1);
1254 CurrentMode = SMESH::Relative;
1256 SetCurrentPlaneParam();
1260 SLOT on new button click: create a new clipping plane
1262 void SMESHGUI_ClippingDlg::ClickOnNew()
1265 SMESH::OrientedPlane* aPlane = SMESH::OrientedPlane::New(myViewWindow);
1266 SMESH::TPlane aTPlane(aPlane);
1267 aPlane->PlaneMode = CurrentMode;
1268 SMESH::TActorList anActorList;
1269 VTK::ActorCollectionCopy aCopy( myViewWindow->getRenderer()->GetActors() );
1270 vtkActorCollection* anAllActors = aCopy.GetActors();
1271 anAllActors->InitTraversal();
1272 while( vtkActor* aVTKActor = anAllActors->GetNextActor() )
1273 if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) )
1274 anActorList.push_back( anActor );
1276 SMESH::TPlaneData aPlaneData(aTPlane, anActorList);
1278 myPlanes.push_back(aPlaneData);
1281 std::for_each( myPlanes.begin(),myPlanes.end(), TSetVisibility( PreviewCheckBox->isChecked() ) );
1282 aPlane->myActor->SetVisibility( false );
1284 bool anIsBlocked = ActorList->blockSignals( true );
1286 SMESH::ComputeBounds( anActorList, myBounds );
1287 myPreviewWidget->PlaceWidget( myBounds[0],myBounds[1],myBounds[2],
1288 myBounds[3],myBounds[4],myBounds[5] );
1290 SetCurrentPlaneParam();
1292 ActorList->blockSignals( anIsBlocked );
1297 SLOT on delete button click: Delete selected clipping plane
1299 void SMESHGUI_ClippingDlg::ClickOnDelete()
1301 if (myPlanes.empty())
1304 int aPlaneIndex = ComboBoxPlanes->currentIndex();
1306 SMESH::TPlaneDataVector::iterator anIter = myPlanes.begin() + aPlaneIndex;
1307 SMESH::TPlaneData aPlaneData = *anIter;
1308 aPlaneData.Plane.GetPointer()->myActor->SetVisibility(false);
1309 myPlanes.erase(anIter);
1311 if(AutoApplyCheckBox->isChecked())
1315 SMESH::RenderViewWindow( myViewWindow );
1319 Set current parameters of selected plane
1321 void SMESHGUI_ClippingDlg::onSelectPlane ( int theIndex )
1323 if ( myPlanes.empty() )
1326 SMESH::TPlaneData aPlaneData = myPlanes[theIndex];
1327 SMESH::OrientedPlane* aPlane = aPlaneData.Plane.GetPointer();
1329 myIsSelectPlane = true;
1330 isOpenGLClipping->setChecked( aPlane->IsOpenGLClipping );
1332 if ( aPlane->PlaneMode == SMESH::Absolute ) {
1333 ModeStackedLayout->setCurrentIndex( 0 );
1334 CurrentMode = SMESH::Absolute;
1335 int anOrientation = aPlane->myAbsoluteOrientation;
1336 // Set plane parameters in the dialog
1337 double anOrigin[3], aDir[3];
1338 anOrigin[0] = aPlane->X;
1339 anOrigin[1] = aPlane->Y;
1340 anOrigin[2] = aPlane->Z;
1341 setOrigin( anOrigin );
1342 aDir[0] = aPlane->Dx;
1343 aDir[1] = aPlane->Dy;
1344 aDir[2] = aPlane->Dz;
1345 setDirection( aDir );
1346 CBAbsoluteOrientation->setCurrentIndex( anOrientation );
1347 onSelectAbsoluteOrientation( anOrientation );
1349 else if ( aPlane->PlaneMode == SMESH::Relative ) {
1350 ModeStackedLayout->setCurrentIndex( 1 );
1351 CurrentMode = SMESH::Relative;
1352 SMESH::Orientation anOrientation = aPlane->GetOrientation();
1353 double aRot[2] = { aPlane->myAngle[0], aPlane->myAngle[1] };
1354 // Set plane parameters in the dialog
1355 setDistance( aPlane->GetDistance() );
1356 setRotation( aRot[0], aRot[1] );
1357 switch ( anOrientation ) {
1359 CBRelativeOrientation->setCurrentIndex(0);
1360 onSelectRelativeOrientation(0);
1363 CBRelativeOrientation->setCurrentIndex(1);
1364 onSelectRelativeOrientation(1);
1367 CBRelativeOrientation->setCurrentIndex(2);
1368 onSelectRelativeOrientation(2);
1372 myIsSelectPlane = false;
1373 SMESH::ComputeBounds( aPlaneData.ActorList, myBounds );
1374 myPreviewWidget->PlaceWidget( myBounds[0], myBounds[1], myBounds[2],
1375 myBounds[3], myBounds[4], myBounds[5] );
1376 SetCurrentPlaneParam();
1379 bool anIsBlocked = ActorList->blockSignals( true );
1381 ActorList->blockSignals( anIsBlocked );
1385 SLOT: called on OpenGLClipping check box toggled
1387 void SMESHGUI_ClippingDlg::onIsOpenGLClipping( bool toggled )
1389 if ( myPlanes.empty() || myIsSelectPlane )
1392 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
1393 SMESH::TPlaneData aPlane = myPlanes[aCurPlaneIndex];
1394 SMESH::OrientedPlane* aPlaneData = aPlane.Plane.GetPointer();
1395 aPlaneData->IsOpenGLClipping = toggled;
1397 if( AutoApplyCheckBox->isChecked() )
1402 SLOT: called on SelectAll check box toggled
1404 void SMESHGUI_ClippingDlg::onSelectAll( int theState )
1406 if( theState == Qt::PartiallyChecked ) {
1407 SelectAllCheckBox->setCheckState( Qt::Checked );
1411 bool anIsBlocked = ActorList->blockSignals( true );
1412 for( int i = 0, n = ActorList->count(); i < n; i++ ) {
1413 if( QListWidgetItem* anItem = ActorList->item( i ) ) {
1414 anItem->setCheckState( theState == Qt::Checked ? Qt::Checked : Qt::Unchecked );
1415 updateActorItem( anItem, false, true );
1418 SelectAllCheckBox->setTristate( false );
1419 ActorList->blockSignals( anIsBlocked );
1420 SetCurrentPlaneParam();
1424 SLOT: called when actor item was changed
1426 void SMESHGUI_ClippingDlg::onActorItemChanged( QListWidgetItem* theItem )
1428 updateActorItem( theItem, true, true );
1429 SetCurrentPlaneParam();
1433 Restore parameters of selected plane
1435 void SMESHGUI_ClippingDlg::SetCurrentPlaneParam()
1437 if ( myPlanes.empty() || myIsSelectPlane )
1440 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
1442 SMESH::TPlaneData aPlaneData = myPlanes[aCurPlaneIndex];
1443 SMESH::OrientedPlane* aPlane = aPlaneData.Plane.GetPointer();
1445 if ( aPlane->PlaneMode == SMESH::Absolute ) {
1446 aPlane->myAbsoluteOrientation = CBAbsoluteOrientation->currentIndex();
1447 aPlane->X = SpinBox_X->value();
1448 aPlane->Y = SpinBox_Y->value();
1449 aPlane->Z = SpinBox_Z->value();
1450 aPlane->Dx = SpinBox_Dx->value();
1451 aPlane->Dy = SpinBox_Dy->value();
1452 aPlane->Dz = SpinBox_Dz->value();
1456 double aDir[2][3] = { {0, 0, 0}, {0, 0, 0} };
1457 static double aCoeff = vtkMath::Pi()/180.0;
1459 double aRot[2] = { getRotation1(), getRotation2() };
1461 if ( aPlane->PlaneMode == SMESH::Absolute )
1462 anOrient = CBAbsoluteOrientation->currentIndex();
1463 else if ( aPlane->PlaneMode == SMESH::Relative )
1464 anOrient = CBRelativeOrientation->currentIndex() + 1;
1466 if ( aPlane->PlaneMode == SMESH::Relative ) {
1467 aPlane->myAngle[0] = aRot[0];
1468 aPlane->myAngle[1] = aRot[1];
1469 aPlane->SetOrientation( SMESH::Orientation( CBRelativeOrientation->currentIndex() ) );
1470 aPlane->SetDistance( getDistance() );
1473 if ( anOrient == 0 ) {
1474 // compute a direction for plane in absolute mode
1475 double znam = sqrt( aPlane->Dx*aPlane->Dx + aPlane->Dy*aPlane->Dy + aPlane->Dz*aPlane->Dz );
1476 double aRotation = acos( aPlane->Dy/znam )/aCoeff;
1477 if ( aPlane->Dy >= 0.0 && aPlane->Dz >= 0.0 ) aRot[0] = 90.0 + aRotation;
1478 else if ( aPlane->Dy >= 0.0 && aPlane->Dz < 0.0 ) aRot[0] = 90.0 - aRotation;
1479 else if ( aPlane->Dy < 0.0 && aPlane->Dz >= 0.0 ) aRot[0] = aRotation - 90.0;
1480 else if ( aPlane->Dy < 0.0 && aPlane->Dz < 0.0 ) aRot[0] = 270.0 - aRotation;
1482 aRotation = acos( aPlane->Dx/znam )/aCoeff;
1483 if ( aPlane->Dx >= 0.0 && aPlane->Dz >= 0.0 ) aRot[1] = 90.0 + aRotation;
1484 else if ( aPlane->Dx >= 0.0 && aPlane->Dz < 0.0 ) aRot[1] = 90.0 - aRotation;
1485 else if ( aPlane->Dx < 0.0 && aPlane->Dz >= 0.0 ) aRot[1] = aRotation - 90.0;
1486 else if ( aPlane->Dx < 0.0 && aPlane->Dz < 0.0 ) aRot[1] = 270.0 - aRotation;
1490 rotationToNormal( aRot, anOrient, aNormal, aDir );
1493 SMESH::TActorList anActorList = aPlaneData.ActorList;
1498 aDistance = getDistance();
1499 if ( aPlane->PlaneMode == SMESH::Absolute ) {
1500 aNormal[0] = aPlane->Dx;
1501 aNormal[1] = aPlane->Dy;
1502 aNormal[2] = aPlane->Dz;
1505 bool anIsOk = SMESH::ComputeClippingPlaneParameters( anActorList,
1511 if ( aPlane->PlaneMode == SMESH::Absolute ) {
1512 anOrigin[0] = aPlane->X;
1513 anOrigin[1] = aPlane->Y;
1514 anOrigin[2] = aPlane->Z;
1518 aPlane->SetNormal( aNormal );
1519 aPlane->SetOrigin( anOrigin );
1521 double aPnt[3] = { ( aBounds[0] + aBounds[1] ) / 2.,
1522 ( aBounds[2] + aBounds[3] ) / 2.,
1523 ( aBounds[4] + aBounds[5] ) / 2. };
1525 double aDel = pow( pow( aBounds[1] - aBounds[0], 2 ) +
1526 pow( aBounds[3] - aBounds[2], 2 ) +
1527 pow( aBounds[5] - aBounds[4], 2 ), 0.5 );
1529 double aDelta[2][3] = { { aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel },
1530 { aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel } };
1531 double aParam, aPnt0[3], aPnt1[3], aPnt2[3];
1533 double aPnt01[3] = { aPnt[0] - aDelta[0][0] - aDelta[1][0],
1534 aPnt[1] - aDelta[0][1] - aDelta[1][1],
1535 aPnt[2] - aDelta[0][2] - aDelta[1][2] };
1536 double aPnt02[3] = { aPnt01[0] + aNormal[0],
1537 aPnt01[1] + aNormal[1],
1538 aPnt01[2] + aNormal[2] };
1539 vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0);
1541 double aPnt11[3] = { aPnt[0] - aDelta[0][0] + aDelta[1][0],
1542 aPnt[1] - aDelta[0][1] + aDelta[1][1],
1543 aPnt[2] - aDelta[0][2] + aDelta[1][2] };
1544 double aPnt12[3] = { aPnt11[0] + aNormal[0],
1545 aPnt11[1] + aNormal[1],
1546 aPnt11[2] + aNormal[2] };
1547 vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1);
1549 double aPnt21[3] = { aPnt[0] + aDelta[0][0] - aDelta[1][0],
1550 aPnt[1] + aDelta[0][1] - aDelta[1][1],
1551 aPnt[2] + aDelta[0][2] - aDelta[1][2] };
1552 double aPnt22[3] = { aPnt21[0] + aNormal[0],
1553 aPnt21[1] + aNormal[1],
1554 aPnt21[2] + aNormal[2] };
1555 vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2);
1557 vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource;
1559 aPlaneSource->SetNormal( aNormal[0], aNormal[1], aNormal[2] );
1560 aPlaneSource->SetOrigin( aPnt0[0], aPnt0[1], aPnt0[2] );
1561 aPlaneSource->SetPoint1( aPnt1[0], aPnt1[1], aPnt1[2] );
1562 aPlaneSource->SetPoint2( aPnt2[0], aPnt2[1], aPnt2[2] );
1563 aPlaneSource->Update();
1566 setBoundsForPreviewWidget();
1568 myPreviewWidget->SetOrigin( anOrigin );
1569 myPreviewWidget->SetNormal( aNormal );
1571 if(AutoApplyCheckBox->isChecked())
1574 SMESH::RenderViewWindow( myViewWindow );
1578 Set current bounds for preview widget
1580 void SMESHGUI_ClippingDlg::setBoundsForPreviewWidget()
1582 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
1583 SMESH::TPlaneData aPlaneData = myPlanes[aCurPlaneIndex];
1584 SMESH::OrientedPlane* aPlane = aPlaneData.Plane.GetPointer();
1585 SMESH::TActorList anActorList = aPlaneData.ActorList;
1587 double* anOrigin = aPlane->GetOrigin();
1590 SMESH::ComputeBounds( anActorList, aBounds );
1592 bool isBoundsChanged = false;
1594 if( myIsPreviewMoved ) {
1595 // if widget has moved by hand the bounds can to minimize
1596 if( anOrigin[0] > myBounds[0] && anOrigin[0] < aBounds[0] ) {
1597 myBounds[0] = anOrigin[0]; isBoundsChanged = true; }
1598 if( anOrigin[0] < myBounds[1] && anOrigin[0] > aBounds[1] ) {
1599 myBounds[1] = anOrigin[0]; isBoundsChanged = true; }
1600 if( anOrigin[1] > myBounds[2] && anOrigin[1] < aBounds[2] ) {
1601 myBounds[2] = anOrigin[1]; isBoundsChanged = true; }
1602 if( anOrigin[1] < myBounds[3] && anOrigin[1] > aBounds[3] ) {
1603 myBounds[3] = anOrigin[1]; isBoundsChanged = true; }
1604 if( anOrigin[2] > myBounds[4] && anOrigin[2] < aBounds[4] ) {
1605 myBounds[4] = anOrigin[2]; isBoundsChanged = true; }
1606 if( anOrigin[2] < myBounds[5] && anOrigin[2] > aBounds[5] ) {
1607 myBounds[5] = anOrigin[2]; isBoundsChanged = true; }
1610 // if widget has moved by dialog data the bounds can to take necessary size
1611 if( anOrigin[0] < aBounds[0] ) {
1612 myBounds[0] = anOrigin[0]; isBoundsChanged = true; }
1613 if( anOrigin[0] > aBounds[1] ) {
1614 myBounds[1] = anOrigin[0]; isBoundsChanged = true; }
1615 if( anOrigin[1] < aBounds[2] ) {
1616 myBounds[2] = anOrigin[1]; isBoundsChanged = true; }
1617 if( anOrigin[1] > aBounds[3] ) {
1618 myBounds[3] = anOrigin[1]; isBoundsChanged = true; }
1619 if( anOrigin[2] < aBounds[4] ) {
1620 myBounds[4] = anOrigin[2]; isBoundsChanged = true; }
1621 if( anOrigin[2] > aBounds[5] ) {
1622 myBounds[5] = anOrigin[2]; isBoundsChanged = true; }
1625 if( isBoundsChanged )
1626 myPreviewWidget->PlaceWidget( myBounds[0],myBounds[1],myBounds[2],
1627 myBounds[3],myBounds[4],myBounds[5] );
1628 else if( !myIsPreviewMoved )
1629 myPreviewWidget->PlaceWidget( aBounds[0],aBounds[1],aBounds[2],
1630 aBounds[3],aBounds[4],aBounds[5] );
1635 Convert absolute coordinates of plane to relative mode
1637 void SMESHGUI_ClippingDlg::absolutePlaneToRelative ( double theOrigin[3], double theDir[3] )
1641 aRot[0] = getRotation1();
1642 aRot[1] = getRotation2();
1644 double eps = 0.0001;
1646 int anOrientation = CBRelativeOrientation->currentIndex();
1647 double aDirection[3];
1648 double aRotation1, aRotation2;
1649 switch( anOrientation ) {
1651 aDirection[0] = theDir[0] + eps;
1652 aDirection[1] = theDir[1] + eps;
1653 aDirection[2] = theDir[2] + eps;
1654 aRotation1 = atan2( theDir[2], theDir[1] )*180.0/M_PI;
1655 aRotation2 = atan2( theDir[2], theDir[0] )*180.0/M_PI;
1658 aDirection[0] = theDir[1] + eps;
1659 aDirection[1] = theDir[2] + eps;
1660 aDirection[2] = theDir[0] + eps;
1661 aRotation1 = atan2( theDir[0], theDir[2] )*180.0/M_PI;
1662 aRotation2 = atan2( theDir[0], theDir[1] )*180.0/M_PI;
1665 aDirection[0] = theDir[2] + eps;
1666 aDirection[1] = theDir[0] + eps;
1667 aDirection[2] = theDir[1] + eps;
1668 aRotation1 = atan2( theDir[1], theDir[0] )*180.0/M_PI;
1669 aRotation2 = atan2( theDir[1], theDir[2] )*180.0/M_PI;
1673 if( aDirection[0] > 0 && aDirection[1] > 0 && aDirection[2] > 0 && aRot[0] <= 0 ) {
1674 aRot[0] = aRotation1 - 90.0; aRot[1] = aRotation2 - 90.0; }
1675 else if( aDirection[0] > 0 && aDirection[1] > 0 && aDirection[2] > 0 && aRot[0] > 0 ) {
1676 aRot[0] = aRotation1 + 90.0; aRot[1] = aRotation2 + 90.0; }
1677 else if( aDirection[0] > 0 && aDirection[1] > 0 && aDirection[2] < 0 && aRot[0] <= 0 ) {
1678 aRot[0] = aRotation1 - 90.0; aRot[1] = aRotation2 + 90.0; }
1679 else if( aDirection[0] > 0 && aDirection[1] > 0 && aDirection[2] < 0 && aRot[0] > 0 ) {
1680 aRot[0] = aRotation1 + 90.0; aRot[1] = aRotation2 - 90.0; }
1681 else if( aDirection[0] > 0 && aDirection[1] < 0 && aDirection[2] > 0 && aRot[0] <= 0 ) {
1682 aRot[0] = aRotation1 - 270.0; aRot[1] = aRotation2 + 90.0; }
1683 else if( aDirection[0] > 0 && aDirection[1] < 0 && aDirection[2] > 0 && aRot[0] > 0 ) {
1684 aRot[0] = aRotation1 - 90.0; aRot[1] = aRotation2 - 90.0; }
1685 else if( aDirection[0] > 0 && aDirection[1] < 0 && aDirection[2] < 0 && aRot[0] <= 0 ) {
1686 aRot[0] = aRotation1 + 90.0; aRot[1] = aRotation2 - 90.0; }
1687 else if( aDirection[0] > 0 && aDirection[1] < 0 && aDirection[2] < 0 && aRot[0] > 0 ) {
1688 aRot[0] = aRotation1 + 270.0; aRot[1] = aRotation2 + 90.0; }
1689 else if( aDirection[0] < 0 && aDirection[1] > 0 && aDirection[2] > 0 && aRot[0] <= 0 ) {
1690 aRot[0] = aRotation1 - 90.0; aRot[1] = aRotation2 - 90.0; }
1691 else if( aDirection[0] < 0 && aDirection[1] > 0 && aDirection[2] > 0 && aRot[0] > 0 ) {
1692 aRot[0] = aRotation1 + 90.0; aRot[1] = aRotation2 - 270.0; }
1693 else if( aDirection[0] < 0 && aDirection[1] > 0 && aDirection[2] < 0 && aRot[0] <= 0 ) {
1694 aRot[0] = aRotation1 - 90.0; aRot[1] = aRotation2 + 90.0; }
1695 else if( aDirection[0] < 0 && aDirection[1] > 0 && aDirection[2] < 0 && aRot[0] > 0 ) {
1696 aRot[0] = aRotation1 + 90.0; aRot[1] = aRotation2 + 270.0; }
1697 else if( aDirection[0] < 0 && aDirection[1] < 0 && aDirection[2] > 0 && aRot[0] <= 0 ) {
1698 aRot[0] = aRotation1 - 270.0; aRot[1] = aRotation2 - 270.0; }
1699 else if( aDirection[0] < 0 && aDirection[1] < 0 && aDirection[2] > 0 && aRot[0] > 0 ) {
1700 aRot[0] = aRotation1 - 90.0; aRot[1] = aRotation2 - 90.0; }
1701 else if( aDirection[0] < 0 && aDirection[1] < 0 && aDirection[2] < 0 && aRot[0] <= 0 ) {
1702 aRot[0] = aRotation1 + 90.0; aRot[1] = aRotation2 + 270.0; }
1703 else if( aDirection[0] < 0 && aDirection[1] < 0 && aDirection[2] < 0 && aRot[0] > 0 ) {
1704 aRot[0] = aRotation1 + 270.0; aRot[1] = aRotation2 + 90.0; }
1706 SliderRotation1HasMoved( round( aRot[0] ) );
1707 SliderRotation1->setValue( round( aRot[0] ) );
1708 SliderRotation2HasMoved( round( aRot[1] ) );
1709 SliderRotation2->setValue( round( aRot[1] ) );
1711 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
1712 const SMESH::TPlaneData& aPlaneData = myPlanes[ aCurPlaneIndex ];
1713 const SMESH::TActorList& anActorList = aPlaneData.ActorList;
1717 SMESH::ComputeBounds( anActorList, aBounds );
1718 SMESH::PositionToDistance( aBounds, theDir, theOrigin, aDist );
1719 aDist = 1.0 - aDist;
1722 else if( aDist < 0.0 )
1725 SliderDistanceHasMoved( round( aDist*100 ) );
1726 SliderDistance->setValue( round( aDist*100 ) );
1731 SLOT: called on preview check box toggled
1733 void SMESHGUI_ClippingDlg::OnPreviewToggle (bool theIsToggled)
1735 std::for_each( myPlanes.begin(), myPlanes.end(), TSetVisibility( theIsToggled ) );
1736 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
1737 SMESH::TPlaneData aPlane = myPlanes[aCurPlaneIndex];
1738 SMESH::OrientedPlane* aPlaneData = aPlane.Plane.GetPointer();
1739 aPlaneData->myActor->SetVisibility( false );
1741 myPreviewWidget->On();
1743 myPreviewWidget->Off();
1744 SMESH::RenderViewWindow( myViewWindow );
1748 SLOT: called on Auto Apply check box toggled
1750 void SMESHGUI_ClippingDlg::onAutoApply(bool toggled)
1752 if ( toggled ) ClickOnApply();
1756 SLOT on ok button click: sets cutting plane and closes dialog
1758 void SMESHGUI_ClippingDlg::ClickOnOk()
1766 SLOT on Apply button click: sets cutting plane and update viewer
1768 void SMESHGUI_ClippingDlg::ClickOnApply()
1771 SUIT_OverrideCursor wc;
1773 QWidget *aCurrWid = this->focusWidget();
1774 aCurrWid->clearFocus();
1775 aCurrWid->setFocus();
1777 SMESHGUI_ClippingPlaneInfoMap& aClippingPlaneInfoMap = mySMESHGUI->getClippingPlaneInfoMap();
1778 SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = aClippingPlaneInfoMap[ myViewWindow->getViewManager() ];
1780 // clean memory allocated for planes
1781 SMESHGUI_ClippingPlaneInfoList::iterator anIter1 = aClippingPlaneInfoList.begin();
1782 for( ; anIter1 != aClippingPlaneInfoList.end(); anIter1++ )
1783 if( SMESH::OrientedPlane* aPlane = (*anIter1).Plane )
1786 aClippingPlaneInfoList.clear();
1788 VTK::ActorCollectionCopy aCopy( myViewWindow->getRenderer()->GetActors() );
1789 vtkActorCollection* anAllActors = aCopy.GetActors();
1790 anAllActors->InitTraversal();
1791 while( vtkActor* aVTKActor = anAllActors->GetNextActor() )
1792 if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) )
1793 anActor->RemoveAllClippingPlanes();
1795 SMESH::TPlaneDataVector::iterator anIter2 = myPlanes.begin();
1796 for( ; anIter2 != myPlanes.end(); anIter2++ ) {
1797 SMESH::TPlaneData aPlaneData = *anIter2;
1798 SMESH::TPlane aPlane = aPlaneData.Plane;
1799 SMESH::TActorList anActorList = aPlaneData.ActorList;
1801 // the check is disabled to support planes with empty actor list
1802 //if( anActorList.empty() )
1805 SMESH::OrientedPlane* anOrientedPlane = SMESH::OrientedPlane::New(myViewWindow);
1806 anOrientedPlane->ShallowCopy(aPlane.GetPointer());
1807 SMESH::TActorList::iterator anIter3 = anActorList.begin();
1808 for( ; anIter3 != anActorList.end(); anIter3++ )
1809 if( vtkActor* aVTKActor = *anIter3 )
1810 if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) {
1811 if( anOrientedPlane->IsOpenGLClipping )
1812 anActor->AddOpenGLClippingPlane( anOrientedPlane->InvertPlane() );
1814 anActor->AddClippingPlane( anOrientedPlane );
1817 SMESH::ClippingPlaneInfo aClippingPlaneInfo;
1818 aClippingPlaneInfo.Plane = anOrientedPlane;
1819 aClippingPlaneInfo.ActorList = anActorList;
1821 aClippingPlaneInfoList.push_back( aClippingPlaneInfo );
1824 SMESH_Actor* anSMESHActor;
1825 anAllActors->InitTraversal();
1826 while( vtkActor* aVTKActor = anAllActors->GetNextActor() )
1827 if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) {
1828 anSMESHActor = anActor;
1829 anActor->SetOpenGLClippingPlane();
1832 SMESH::RenderViewWindow( myViewWindow );
1837 SLOT on help button click: opens a help page
1839 void SMESHGUI_ClippingDlg::ClickOnHelp()
1841 LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
1843 app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
1847 platform = "winapplication";
1849 platform = "application";
1851 SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
1852 tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
1853 arg(app->resourceMgr()->stringValue("ExternalBrowser",
1855 arg(myHelpFileName));
1860 SLOT: Called when value of slider distance change
1862 void SMESHGUI_ClippingDlg::SliderDistanceHasMoved( int value )
1864 double new_value = value/100.;
1865 TLValueDistance->setText( QString("%1").arg( new_value ) );
1866 SetCurrentPlaneParam();
1870 SLOT: Called when value of slider rotation1 change
1872 void SMESHGUI_ClippingDlg::SliderRotation1HasMoved( int value )
1874 TLValueRotation1->setText( QString("%1\xB0").arg( value ) );
1875 SetCurrentPlaneParam();
1879 SLOT: Called when value of slider rotation2 change
1881 void SMESHGUI_ClippingDlg::SliderRotation2HasMoved( int value )
1883 TLValueRotation2->setText( QString("%1\xB0").arg( value ) );
1884 SetCurrentPlaneParam();
1887 void SMESHGUI_ClippingDlg::onSelectAbsoluteOrientation( int mode )
1889 bool isUserMode = (mode==0);
1891 TextLabelX->setEnabled( isUserMode );
1892 TextLabelY->setEnabled( isUserMode );
1893 TextLabelZ->setEnabled( isUserMode );
1895 SpinBox_X->setEnabled( isUserMode );
1896 SpinBox_Y->setEnabled( isUserMode );
1897 SpinBox_Z->setEnabled( isUserMode );
1899 TextLabelDx->setEnabled( isUserMode );
1900 TextLabelDy->setEnabled( isUserMode );
1901 TextLabelDz->setEnabled( isUserMode );
1903 SpinBox_Dx->setEnabled( isUserMode );
1904 SpinBox_Dy->setEnabled( isUserMode );
1905 SpinBox_Dz->setEnabled( isUserMode );
1910 double aDx = 0, aDy = 0, aDz = 0;
1915 TextLabelZ->setEnabled( true );
1916 SpinBox_Z->setEnabled( true );
1917 SpinBox_Z->setFocus();
1919 else if ( mode == 2 )
1922 TextLabelX->setEnabled( true );
1923 SpinBox_X->setEnabled( true );
1924 SpinBox_X->setFocus();
1926 else if ( mode == 3 )
1929 TextLabelY->setEnabled( true );
1930 SpinBox_Y->setEnabled( true );
1931 SpinBox_Y->setFocus();
1934 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
1935 SMESH::TPlaneData aPlane = myPlanes[aCurPlaneIndex];
1936 SMESH::OrientedPlane* aPlaneData = aPlane.Plane.GetPointer();
1938 if ( aPlaneData->IsInvert == true ) {
1939 aDx = -aDx; aDy = -aDy; aDz = -aDz;
1942 myIsSelectPlane = true;
1943 SpinBox_Dx->setValue( aDx );
1944 SpinBox_Dy->setValue( aDy );
1945 SpinBox_Dz->setValue( aDz );
1946 myIsSelectPlane = false;
1948 SetCurrentPlaneParam();
1952 SLOT: called on orientation of clipping plane in relative mode changed
1954 void SMESHGUI_ClippingDlg::onSelectRelativeOrientation ( int theItem )
1956 if ( myPlanes.empty() )
1959 if ( theItem == 0 ) {
1960 TextLabelRotation1->setText( tr( "ROTATION_AROUND_X_Y2Z" ) );
1961 TextLabelRotation2->setText( tr( "ROTATION_AROUND_Y_X2Z" ) );
1963 else if ( theItem == 1 ) {
1964 TextLabelRotation1->setText( tr( "ROTATION_AROUND_Y_Z2X" ) );
1965 TextLabelRotation2->setText( tr( "ROTATION_AROUND_Z_Y2X" ) );
1967 else if ( theItem == 2 ) {
1968 TextLabelRotation1->setText( tr( "ROTATION_AROUND_Z_X2Y" ) );
1969 TextLabelRotation2->setText( tr( "ROTATION_AROUND_X_Z2Y" ) );
1972 if( (QComboBox*)sender() == CBRelativeOrientation )
1973 SetCurrentPlaneParam();
1977 SLOT on reset button click: sets default values
1979 void SMESHGUI_ClippingDlg::onReset()
1981 myIsSelectPlane = true;
1982 SpinBox_X->setValue(0);
1983 SpinBox_Y->setValue(0);
1984 SpinBox_Z->setValue(0);
1985 myIsSelectPlane = false;
1987 SetCurrentPlaneParam();
1991 SLOT on invert button click: inverts normal of cutting plane
1993 void SMESHGUI_ClippingDlg::onInvert()
1995 double Dx = SpinBox_Dx->value();
1996 double Dy = SpinBox_Dy->value();
1997 double Dz = SpinBox_Dz->value();
1999 myIsSelectPlane = true;
2000 SpinBox_Dx->setValue( -Dx );
2001 SpinBox_Dy->setValue( -Dy );
2002 SpinBox_Dz->setValue( -Dz );
2003 myIsSelectPlane = false;
2005 if ( !myPlanes.empty() ) {
2006 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
2007 SMESH::TPlaneData aPlane = myPlanes[aCurPlaneIndex];
2008 SMESH::OrientedPlane* aPlaneData = aPlane.Plane.GetPointer();
2009 aPlaneData->IsInvert = !aPlaneData->IsInvert;
2011 SetCurrentPlaneParam();