Back to index

salome-gui  6.5.0
OCCViewer_ClippingDlg.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 #include "OCCViewer_ClippingDlg.h"
00024 
00025 #include <QtxDoubleSpinBox.h>
00026 #include <QtxAction.h>
00027 
00028 #include "SUIT_Session.h"
00029 #include "SUIT_ViewWindow.h"
00030 #include "SUIT_ViewManager.h"
00031 #include "OCCViewer_ViewWindow.h"
00032 #include "OCCViewer_ViewPort3d.h"
00033 #include "OCCViewer_ViewModel.h"
00034 
00035 #include <V3d_View.hxx>
00036 #include <Geom_Plane.hxx>
00037 #include <Prs3d_Presentation.hxx>
00038 #include <AIS_ListIteratorOfListOfInteractive.hxx>
00039 #include <AIS_ListOfInteractive.hxx>
00040 #include <AIS_InteractiveObject.hxx>
00041 #include <AIS_InteractiveContext.hxx>
00042 #include <IntAna_IntConicQuad.hxx>
00043 #include <gp_Lin.hxx>
00044 #include <gp_Pln.hxx>
00045 
00046 // QT Includes
00047 #include <QApplication>
00048 #include <QGroupBox>
00049 #include <QHBoxLayout>
00050 #include <QVBoxLayout>
00051 #include <QGridLayout>
00052 #include <QLabel>
00053 #include <QPushButton>
00054 #include <QComboBox>
00055 #include <QCheckBox>
00056 
00065 OCCViewer_ClippingDlg::OCCViewer_ClippingDlg( OCCViewer_ViewWindow* view, const char* name, bool modal, Qt::WindowFlags fl )
00066 : QDialog( view, Qt::WindowTitleHint | Qt::WindowSystemMenuHint ),
00067   myView( view )
00068 {
00069   setObjectName( "OCCViewer_ClippingDlg" );
00070   setModal( modal );
00071 
00072   setWindowTitle( tr( "Clipping" ) );
00073   
00074   QVBoxLayout* topLayout = new QVBoxLayout( this );
00075   topLayout->setMargin( 11 ); topLayout->setSpacing( 6 );
00076   
00077   /***************************************************************/
00078   GroupPoint = new QGroupBox( this );
00079   GroupPoint->setObjectName( "GroupPoint" );
00080   GroupPoint->setTitle( tr("Base point") );
00081   QGridLayout* GroupPointLayout = new QGridLayout( GroupPoint );
00082   GroupPointLayout->setAlignment( Qt::AlignTop );
00083   GroupPointLayout->setSpacing( 6 );
00084   GroupPointLayout->setMargin( 11 );
00085   
00086   // Controls
00087   const double min = -1e+7;
00088   const double max =  1e+7;
00089   const double step = 5;
00090   const int precision = 3;
00091 
00092   TextLabelX = new QLabel( GroupPoint );
00093   TextLabelX->setObjectName( "TextLabelX" );
00094   TextLabelX->setText( tr("X:") );
00095   GroupPointLayout->addWidget( TextLabelX, 0, 0 );
00096   
00097   SpinBox_X = new QtxDoubleSpinBox( min, max, step, GroupPoint );
00098   SpinBox_X->setObjectName("SpinBox_X" );
00099   SpinBox_X->setDecimals( precision );
00100   GroupPointLayout->addWidget( SpinBox_X, 0, 1 );
00101 
00102   TextLabelY = new QLabel( GroupPoint );
00103   TextLabelY->setObjectName( "TextLabelY" );
00104   TextLabelY->setText( tr("Y:") );
00105   GroupPointLayout->addWidget( TextLabelY, 0, 2 );
00106 
00107   SpinBox_Y = new QtxDoubleSpinBox( min, max, step, GroupPoint );
00108   SpinBox_Y->setObjectName("SpinBox_Y" );
00109   SpinBox_Y->setDecimals( precision );
00110   GroupPointLayout->addWidget( SpinBox_Y, 0, 3 );
00111 
00112   TextLabelZ = new QLabel( GroupPoint );
00113   TextLabelZ->setObjectName( "TextLabelZ" );
00114   TextLabelZ->setText( tr("Z:") );
00115   GroupPointLayout->addWidget( TextLabelZ, 0, 4 );
00116 
00117   SpinBox_Z = new QtxDoubleSpinBox( min, max, step, GroupPoint );
00118   SpinBox_Z->setObjectName("SpinBox_Z" );
00119   SpinBox_Z->setDecimals( precision );
00120   GroupPointLayout->addWidget( SpinBox_Z, 0, 5 );
00121 
00122   resetButton  = new QPushButton( GroupPoint );
00123   resetButton->setObjectName( "resetButton" );
00124   resetButton->setText( tr( "Reset"  ) );
00125   GroupPointLayout->addWidget( resetButton, 0, 6 );
00126 
00127   /***************************************************************/
00128   GroupDirection = new QGroupBox( this );
00129   GroupDirection->setObjectName( "GroupDirection" );
00130   GroupDirection->setTitle( tr("Direction") );
00131   QGridLayout* GroupDirectionLayout = new QGridLayout( GroupDirection );
00132   GroupDirectionLayout->setAlignment( Qt::AlignTop );
00133   GroupDirectionLayout->setSpacing( 6 );
00134   GroupDirectionLayout->setMargin( 11 );
00135   
00136   // Controls
00137   TextLabelDx = new QLabel( GroupDirection );
00138   TextLabelDx->setObjectName( "TextLabelDx" );
00139   TextLabelDx->setText( tr("Dx:") );
00140   GroupDirectionLayout->addWidget( TextLabelDx, 0, 0 );
00141   
00142   SpinBox_Dx = new QtxDoubleSpinBox( min, max, step, GroupDirection );
00143   SpinBox_Dx->setObjectName("SpinBox_Dx" );
00144   SpinBox_Dx->setDecimals( precision );
00145   GroupDirectionLayout->addWidget( SpinBox_Dx, 0, 1 );
00146 
00147   TextLabelDy = new QLabel( GroupDirection );
00148   TextLabelDy->setObjectName( "TextLabelDy" );
00149   TextLabelDy->setText( tr("Dy:") );
00150   GroupDirectionLayout->addWidget( TextLabelDy, 0, 2 );
00151   
00152   SpinBox_Dy = new QtxDoubleSpinBox( min, max, step, GroupDirection );
00153   SpinBox_Dy->setObjectName("SpinBox_Dy" );
00154   SpinBox_Dy->setDecimals( precision );
00155   GroupDirectionLayout->addWidget( SpinBox_Dy, 0, 3 );
00156 
00157   TextLabelDz = new QLabel( GroupDirection );
00158   TextLabelDz->setObjectName( "TextLabelDz" );
00159   TextLabelDz->setText( tr("Dz:") );
00160   GroupDirectionLayout->addWidget( TextLabelDz, 0, 4 );
00161   
00162   SpinBox_Dz = new QtxDoubleSpinBox( min, max, step, GroupDirection );
00163   SpinBox_Dz->setObjectName("SpinBox_Dz" );
00164   SpinBox_Dz->setDecimals( precision );
00165   GroupDirectionLayout->addWidget( SpinBox_Dz, 0, 5 );
00166 
00167   invertButton  = new QPushButton( GroupDirection );
00168   invertButton->setObjectName( "invertButton" );
00169   invertButton->setText( tr( "Invert"  ) );
00170   GroupDirectionLayout->addWidget( invertButton, 0, 6 );
00171  
00172   DirectionCB = new QComboBox( GroupDirection );
00173   DirectionCB->setObjectName( "DirectionCB" );
00174   DirectionCB->insertItem(DirectionCB->count(),tr("CUSTOM"));
00175   DirectionCB->insertItem(DirectionCB->count(),tr("||X-Y"));
00176   DirectionCB->insertItem(DirectionCB->count(),tr("||Y-Z"));
00177   DirectionCB->insertItem(DirectionCB->count(),tr("||Z-X"));
00178   GroupDirectionLayout->addWidget( DirectionCB, 1, 0, 1, 6 );
00179   
00180   /***************************************************************/
00181   
00182   PreviewChB = new QCheckBox( tr("Preview") ,this );
00183   PreviewChB->setObjectName( "PreviewChB" );
00184   PreviewChB->setChecked( true );
00185   
00186   /***************************************************************/
00187   QGroupBox* GroupButtons = new QGroupBox( this );
00188   GroupButtons->setObjectName( "GroupButtons" );
00189   QHBoxLayout* GroupButtonsLayout = new QHBoxLayout( GroupButtons );
00190   GroupButtonsLayout->setAlignment( Qt::AlignTop );
00191   GroupButtonsLayout->setMargin( 11 ); GroupButtonsLayout->setSpacing( 6 );
00192   
00193   buttonApply = new QPushButton( GroupButtons );
00194   buttonApply->setObjectName( "buttonApply" );
00195   buttonApply->setText( tr( "BUT_APPLY"  ) );
00196   buttonApply->setAutoDefault( TRUE ); 
00197   buttonApply->setDefault( TRUE );
00198   GroupButtonsLayout->addWidget( buttonApply );
00199   
00200   GroupButtonsLayout->addStretch();
00201   
00202   buttonClose = new QPushButton( GroupButtons );
00203   buttonClose->setObjectName( "buttonClose" );
00204   buttonClose->setText( tr( "BUT_CLOSE"  ) );
00205   buttonClose->setAutoDefault( TRUE );
00206   GroupButtonsLayout->addWidget( buttonClose );
00207 
00208   /***************************************************************/
00209   
00210   topLayout->addWidget( GroupPoint );
00211   topLayout->addWidget( GroupDirection );
00212   
00213   topLayout->addWidget( PreviewChB );
00214 
00215   topLayout->addWidget( GroupButtons );
00216 
00217   /* initializations */
00218 
00219   SpinBox_X->setValue( 0.0 );
00220   SpinBox_Y->setValue( 0.0 );
00221   SpinBox_Z->setValue( 0.0 );
00222 
00223   SpinBox_Dx->setValue( 1.0 );
00224   SpinBox_Dy->setValue( 1.0 );
00225   SpinBox_Dz->setValue( 1.0 );
00226 
00227   /* signals and slots connections */
00228   connect( resetButton,  SIGNAL (clicked() ), this, SLOT( onReset() ) );
00229   connect( invertButton, SIGNAL (clicked() ), this, SLOT( onInvert() ) ) ;
00230 
00231   connect( SpinBox_X,  SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
00232   connect( SpinBox_Y,  SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
00233   connect( SpinBox_Z,  SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
00234   connect( SpinBox_Dx, SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
00235   connect( SpinBox_Dy, SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
00236   connect( SpinBox_Dz, SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
00237    
00238   connect( DirectionCB, SIGNAL ( activated ( int ) ), this, SLOT( onModeChanged( int ) ) ) ;
00239 
00240   connect( PreviewChB, SIGNAL ( toggled ( bool ) ), this, SLOT( onPreview( bool ) ) ) ;
00241   
00242   connect( buttonClose, SIGNAL( clicked() ), this, SLOT( ClickOnClose() ) ) ;
00243   connect( buttonApply, SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
00244   
00245   myBusy = false;
00246 
00247   connect(view, SIGNAL(Show( QShowEvent * )), this, SLOT(onViewShow()));
00248   connect(view, SIGNAL(Hide( QHideEvent * )), this, SLOT(onViewHide()));
00249 }
00250 
00255 OCCViewer_ClippingDlg::~ OCCViewer_ClippingDlg()
00256 {
00257   // no need to delete child widgets, Qt does it all for us
00258 }
00259 
00260 
00264 void OCCViewer_ClippingDlg::closeEvent( QCloseEvent* e )
00265 {
00266   erasePreview();
00267   
00268   // Set the clipping plane back
00269   /*Handle(V3d_View) aView3d = myView->getViewPort()->getView();
00270   if ( !aView3d.IsNull() && !myClippingPlane.IsNull() )
00271   aView3d->SetPlaneOn( myClippingPlane );*/
00272   
00273   myAction->setChecked( false );
00274   
00275   QDialog::closeEvent( e );
00276 }
00277 
00278 
00282 void OCCViewer_ClippingDlg::showEvent( QShowEvent* e )
00283 {
00284   //ReserveClippingPlane();
00285   
00286   QDialog::showEvent( e );
00287   onPreview( PreviewChB->isChecked() );
00288 }
00289 
00290 
00294 void OCCViewer_ClippingDlg::hideEvent( QHideEvent* e )
00295 {
00296   erasePreview();
00297   QDialog::hideEvent( e );
00298 }
00299 
00300 
00304 void OCCViewer_ClippingDlg::ClickOnClose()
00305 {
00306   erasePreview();
00307 
00308   // Set the clipping plane back
00309   /*Handle(V3d_View) aView3d = myView->getViewPort()->getView();
00310   if ( !aView3d.IsNull() && !myClippingPlane.IsNull() )
00311     aView3d->SetPlaneOn( myClippingPlane );
00312   */
00313   myAction->setChecked( false );
00314   
00315   reject();
00316 }
00317 
00318 
00322 void OCCViewer_ClippingDlg::ClickOnApply()
00323 {
00324   qApp->processEvents();
00325   QApplication::setOverrideCursor( Qt::WaitCursor );
00326   qApp->processEvents();
00327   
00328   myView->setCuttingPlane( true, SpinBox_X->value() , SpinBox_Y->value() , SpinBox_Z->value(),
00329                                  SpinBox_Dx->value(), SpinBox_Dy->value(), SpinBox_Dz->value() );
00330   
00331   QApplication::restoreOverrideCursor(); 
00332   
00333   erasePreview();
00334   
00335   //ReserveClippingPlane();
00336 }
00337 
00341 void OCCViewer_ClippingDlg::onReset()
00342 {
00343   myBusy = true;
00344   SpinBox_X->setValue(0);
00345   SpinBox_Y->setValue(0);
00346   SpinBox_Z->setValue(0);
00347   myBusy = false;
00348 
00349   if ( PreviewChB->isChecked() )
00350     {
00351       erasePreview();
00352       displayPreview();
00353     }
00354 }
00355 
00359 void OCCViewer_ClippingDlg::onInvert()
00360 {
00361   double Dx = SpinBox_Dx->value();
00362   double Dy = SpinBox_Dy->value();
00363   double Dz = SpinBox_Dz->value();
00364   
00365   myBusy = true;
00366   SpinBox_Dx->setValue( -Dx );
00367   SpinBox_Dy->setValue( -Dy );
00368   SpinBox_Dz->setValue( -Dz );
00369   myBusy = false;
00370 
00371   if ( PreviewChB->isChecked() )
00372     {
00373       erasePreview();
00374       displayPreview();
00375     }
00376 }
00377 
00381 void OCCViewer_ClippingDlg::onModeChanged( int mode )
00382 {
00383   bool isUserMode = (mode==0);
00384   
00385   TextLabelX->setEnabled( isUserMode );
00386   TextLabelY->setEnabled( isUserMode );
00387   TextLabelZ->setEnabled( isUserMode );
00388 
00389   SpinBox_X->setEnabled( isUserMode );
00390   SpinBox_Y->setEnabled( isUserMode );
00391   SpinBox_Z->setEnabled( isUserMode );
00392 
00393   TextLabelDx->setEnabled( isUserMode );
00394   TextLabelDy->setEnabled( isUserMode );
00395   TextLabelDz->setEnabled( isUserMode );
00396 
00397   SpinBox_Dx->setEnabled( isUserMode );
00398   SpinBox_Dy->setEnabled( isUserMode );
00399   SpinBox_Dz->setEnabled( isUserMode );
00400   
00401   if ( isUserMode )
00402     return;
00403 
00404   double aDx = 0, aDy = 0, aDz = 0;
00405 
00406   if ( mode == 1 )
00407     {
00408       aDz = 1;
00409       TextLabelZ->setEnabled( true );
00410       SpinBox_Z->setEnabled( true );
00411       SpinBox_Z->setFocus();
00412     }
00413   else if ( mode == 2 )
00414     {
00415       aDx = 1;
00416       TextLabelX->setEnabled( true );
00417       SpinBox_X->setEnabled( true );
00418       SpinBox_X->setFocus();
00419     }
00420   else if ( mode == 3 )
00421     {
00422       aDy = 1;
00423       TextLabelY->setEnabled( true );
00424       SpinBox_Y->setEnabled( true );
00425       SpinBox_Y->setFocus();
00426     }
00427   
00428   myBusy = true;
00429   SpinBox_Dx->setValue( aDx );
00430   SpinBox_Dy->setValue( aDy );
00431   SpinBox_Dz->setValue( aDz );
00432   myBusy = false;
00433 
00434   if ( PreviewChB->isChecked() )
00435     {
00436       erasePreview();
00437       displayPreview();
00438     }
00439 }
00440 
00441 
00445 void OCCViewer_ClippingDlg::displayPreview()
00446 {
00447   if ( myBusy || !isValid() )
00448     return;
00449 
00450   OCCViewer_Viewer* anOCCViewer = (OCCViewer_Viewer*)myView->getViewManager()->getViewModel();
00451   if (!anOCCViewer)
00452     return;
00453   
00454   Handle(AIS_InteractiveContext) ic = anOCCViewer->getAISContext();
00455 
00456   double aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;
00457   aXMin = aYMin = aZMin = DBL_MAX;
00458   aXMax = aYMax = aZMax = -DBL_MAX;
00459 
00460   bool isFound = false;
00461   AIS_ListOfInteractive aList;
00462   ic->DisplayedObjects( aList );
00463   for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() )
00464   {
00465     Handle(AIS_InteractiveObject) anObj = it.Value();
00466     if ( !anObj.IsNull() && anObj->HasPresentation() &&
00467          !anObj->IsKind( STANDARD_TYPE(AIS_Plane) ) )
00468     {
00469       Handle(Prs3d_Presentation) aPrs = anObj->Presentation();
00470       if ( !aPrs->IsEmpty() && !aPrs->IsInfinite() )
00471       {
00472         isFound = true;
00473         double xmin, ymin, zmin, xmax, ymax, zmax;
00474         aPrs->MinMaxValues( xmin, ymin, zmin, xmax, ymax, zmax );
00475         aXMin = qMin( aXMin, xmin );  aXMax = qMax( aXMax, xmax );
00476         aYMin = qMin( aYMin, ymin );  aYMax = qMax( aYMax, ymax );
00477         aZMin = qMin( aZMin, zmin );  aZMax = qMax( aZMax, zmax );
00478       }
00479     }
00480   }
00481 
00482   double aSize = 50;
00483   
00484   gp_Pnt aBasePnt( SpinBox_X->value(),  SpinBox_Y->value(),  SpinBox_Z->value() );
00485   gp_Dir aNormal( SpinBox_Dx->value(), SpinBox_Dy->value(), SpinBox_Dz->value() );
00486   gp_Pnt aCenter = aBasePnt;
00487   
00488   if ( isFound )
00489     {
00490       // compute clipping plane size
00491       aCenter = gp_Pnt( ( aXMin + aXMax ) / 2, ( aYMin + aYMax ) / 2, ( aZMin + aZMax ) / 2 );
00492       double aDiag = aCenter.Distance(gp_Pnt(aXMax, aYMax, aZMax ))*2;
00493       aSize = aDiag * 1.1;
00494 
00495       // compute clipping plane center ( redefine the base point )
00496       IntAna_IntConicQuad intersector = IntAna_IntConicQuad();
00497       
00498       intersector.Perform( gp_Lin( aCenter, aNormal), gp_Pln( aBasePnt, aNormal), Precision::Confusion() );
00499       if ( intersector.IsDone() && intersector.NbPoints() == 1 )
00500         aBasePnt = intersector.Point( 1 );
00501     }
00502   
00503   myPreviewPlane = new AIS_Plane( new Geom_Plane( aBasePnt, aNormal ) );
00504   myPreviewPlane->SetSize( aSize, aSize );
00505   
00506   // Deactivate clipping planes
00507   //myView->getViewPort()->getView()->SetPlaneOff();
00508   //myView->setPlaneOff();
00509 
00510   ic->Display( myPreviewPlane, 1, -1, false );
00511   ic->SetWidth( myPreviewPlane, 10, false );
00512   ic->SetMaterial( myPreviewPlane, Graphic3d_NOM_PLASTIC, false );
00513   ic->SetTransparency( myPreviewPlane, 0.5, false );
00514   ic->SetColor( myPreviewPlane, Quantity_Color( 85 / 255., 85 / 255., 255 / 255., Quantity_TOC_RGB ), false );
00515   
00516   anOCCViewer->update();
00517 }
00518 
00519 
00523 void OCCViewer_ClippingDlg::erasePreview ()
00524 {
00525   OCCViewer_Viewer* anOCCViewer = (OCCViewer_Viewer*)myView->getViewManager()->getViewModel();
00526   if (!anOCCViewer)
00527     return;
00528   
00529   Handle(AIS_InteractiveContext) ic = anOCCViewer->getAISContext();
00530   
00531   if ( !myPreviewPlane.IsNull() && ic->IsDisplayed( myPreviewPlane ) )
00532     {
00533       ic->Erase( myPreviewPlane, false, false );
00534       ic->Remove( myPreviewPlane, false );
00535       myPreviewPlane.Nullify();
00536     }
00537   
00538   anOCCViewer->update();
00539 }
00540 
00541 
00545 void OCCViewer_ClippingDlg::onValueChanged()
00546 {
00547   if ( PreviewChB->isChecked() )
00548     {
00549       erasePreview();
00550       displayPreview();
00551     }
00552 }
00553 
00554 
00558 void OCCViewer_ClippingDlg::onPreview( bool on )
00559 {
00560   erasePreview();
00561 
00562   if ( on ) 
00563     displayPreview();
00564 }
00565 
00569 bool OCCViewer_ClippingDlg::isValid()
00570 {
00571   return ( SpinBox_Dx->value()!=0 || SpinBox_Dy->value()!=0 || SpinBox_Dz->value()!=0 );
00572 }
00573 
00577 void OCCViewer_ClippingDlg::ReserveClippingPlane()
00578 {
00579   /*Handle(V3d_View) aView3d = myView->getViewPort()->getView();
00580   if ( !aView3d.IsNull() )
00581     {
00582       aView3d->InitActivePlanes();
00583       if ( aView3d->MoreActivePlanes() )
00584         myClippingPlane = aView3d->ActivePlane();
00585         }*/
00586 }
00587 
00588 void OCCViewer_ClippingDlg::onViewShow()
00589 {
00590   if(myAction->isChecked())
00591     show();
00592   else
00593     hide();
00594 }
00595 
00596 void OCCViewer_ClippingDlg::onViewHide()
00597 {
00598   hide();
00599 }
00600