]> SALOME platform Git repositories - modules/gui.git/blob - src/OCCViewer/OCCViewer_ClippingDlg.cxx
Salome HOME
7d60625476f262acb20c027e4d62d46236fde8b7
[modules/gui.git] / src / OCCViewer / OCCViewer_ClippingDlg.cxx
1 #include "OCCViewer_ClippingDlg.h"
2
3 #include <QtxDblSpinBox.h>
4
5 #include "SUIT_Session.h"
6 #include "SUIT_ViewWindow.h"
7 #include "SVTK_ViewWindow.h"
8 #include "SVTK_ViewModel.h"
9 #include "OCCViewer_ViewWindow.h"
10 #include "OCCViewer_ViewPort3d.h"
11
12 #include "utilities.h"
13
14 #include <V3d_View.hxx>
15 #include <V3d.hxx>
16 #include <V3d_Plane.hxx>
17 #include <Geom_Plane.hxx>
18 #include <Prs3d_Presentation.hxx>
19 #include <AIS_ListIteratorOfListOfInteractive.hxx>
20 #include <AIS_ListOfInteractive.hxx>
21 #include <AIS_InteractiveObject.hxx>
22 #include <AIS_InteractiveContext.hxx>
23 #include <IntAna_IntConicQuad.hxx>
24 #include <gp_Lin.hxx>
25 #include <gp_Pln.hxx>
26
27 // QT Includes
28 #include <qapplication.h>
29 #include <qgroupbox.h>
30 #include <qlayout.h>
31 #include <qlabel.h>
32 #include <qpushbutton.h>
33 #include <qcombobox.h>
34 #include <qcheckbox.h>
35
36 //=================================================================================
37 // class    : OCCViewer_ClippingDlg()
38 // purpose  : 
39 //=================================================================================
40 OCCViewer_ClippingDlg::OCCViewer_ClippingDlg( OCCViewer_ViewWindow* view, QWidget* parent, const char* name, bool modal, WFlags fl )
41   : QDialog( parent, "OCCViewer_ClippingDlg", modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu ), myView( view )
42 {
43   setCaption( tr( "Clipping" ) );
44   
45   QVBoxLayout* topLayout = new QVBoxLayout( this );
46   topLayout->setMargin( 11 ); topLayout->setSpacing( 6 );
47   
48   /***************************************************************/
49   GroupPoint = new QGroupBox( this, "GroupPoint" );
50   GroupPoint->setTitle( tr("Base point") );
51   GroupPoint->setColumnLayout(0, Qt::Vertical );
52   GroupPoint->layout()->setSpacing( 0 );
53   GroupPoint->layout()->setMargin( 0 );
54   QGridLayout* GroupPointLayout = new QGridLayout( GroupPoint->layout() );
55   GroupPointLayout->setAlignment( Qt::AlignTop );
56   GroupPointLayout->setSpacing( 6 );
57   GroupPointLayout->setMargin( 11 );
58   
59   // Controls
60   const double min = -1e+06;
61   const double max =  1e+06;
62   const double step = 5;
63
64   TextLabelX = new QLabel( GroupPoint, "TextLabelX" );
65   TextLabelX->setText( tr("X:") );
66   GroupPointLayout->addWidget( TextLabelX, 0, 0 );
67   
68   SpinBox_X = new QtxDblSpinBox( min, max, step, GroupPoint, "SpinBox_X" );
69   GroupPointLayout->addWidget( SpinBox_X, 0, 1 );
70
71   TextLabelY = new QLabel( GroupPoint, "TextLabelY" );
72   TextLabelY->setText( tr("Y:") );
73   GroupPointLayout->addWidget( TextLabelY, 0, 2 );
74
75   SpinBox_Y = new QtxDblSpinBox( min, max, step, GroupPoint, "SpinBox_Y" );
76   GroupPointLayout->addWidget( SpinBox_Y, 0, 3 );
77
78   TextLabelZ = new QLabel( GroupPoint, "TextLabelZ" );
79   TextLabelZ->setText( tr("Z:") );
80   GroupPointLayout->addWidget( TextLabelZ, 0, 4 );
81
82   SpinBox_Z = new QtxDblSpinBox( min, max, step, GroupPoint, "SpinBox_Z" );
83   GroupPointLayout->addWidget( SpinBox_Z, 0, 5 );
84
85   resetButton  = new QPushButton( GroupPoint, "resetButton" );
86   resetButton->setText( tr( "Reset"  ) );
87   GroupPointLayout->addWidget( resetButton, 0, 6 );
88
89   /***************************************************************/
90   GroupDirection = new QGroupBox( this, "GroupDirection" );
91   GroupDirection->setTitle( tr("Direction") );
92   GroupDirection->setColumnLayout(0, Qt::Vertical );
93   GroupDirection->layout()->setSpacing( 0 );
94   GroupDirection->layout()->setMargin( 0 );
95   QGridLayout* GroupDirectionLayout = new QGridLayout( GroupDirection->layout() );
96   GroupDirectionLayout->setAlignment( Qt::AlignTop );
97   GroupDirectionLayout->setSpacing( 6 );
98   GroupDirectionLayout->setMargin( 11 );
99   
100   // Controls
101   TextLabelDx = new QLabel( GroupDirection, "TextLabelDx" );
102   TextLabelDx->setText( tr("Dx:") );
103   GroupDirectionLayout->addWidget( TextLabelDx, 0, 0 );
104   
105   SpinBox_Dx = new QtxDblSpinBox( min, max, step, GroupDirection, "SpinBox_Dx" );
106   GroupDirectionLayout->addWidget( SpinBox_Dx, 0, 1 );
107
108   TextLabelDy = new QLabel( GroupDirection, "TextLabelDy" );
109   TextLabelDy->setText( tr("Dy:") );
110   GroupDirectionLayout->addWidget( TextLabelDy, 0, 2 );
111   
112   SpinBox_Dy = new QtxDblSpinBox( min, max, step, GroupDirection, "SpinBox_Dy" );
113   GroupDirectionLayout->addWidget( SpinBox_Dy, 0, 3 );
114
115   TextLabelDz = new QLabel( GroupDirection, "TextLabelDz" );
116   TextLabelDz->setText( tr("Dz:") );
117   GroupDirectionLayout->addWidget( TextLabelDz, 0, 4 );
118   
119   SpinBox_Dz = new QtxDblSpinBox( min, max, step, GroupDirection, "SpinBox_Dz" );
120   GroupDirectionLayout->addWidget( SpinBox_Dz, 0, 5 );
121
122   invertButton  = new QPushButton( GroupDirection, "invertButton" );
123   invertButton->setText( tr( "Invert"  ) );
124   GroupDirectionLayout->addWidget( invertButton, 0, 6 );
125  
126   DirectionCB = new QComboBox( GroupDirection, "DirectionCB" );
127   DirectionCB->insertItem(tr("CUSTOM"));
128   DirectionCB->insertItem(tr("||X-Y"));
129   DirectionCB->insertItem(tr("||Y-Z"));
130   DirectionCB->insertItem(tr("||Z-X"));
131   GroupDirectionLayout->addMultiCellWidget( DirectionCB, 1, 1, 0, 5 );
132   
133   /***************************************************************/
134   
135   PreviewChB = new QCheckBox( tr("Preview") ,this, "PreviewChB" );
136   PreviewChB->setChecked( true );
137   
138   /***************************************************************/
139   QGroupBox* GroupButtons = new QGroupBox( this, "GroupButtons" );
140   GroupButtons->setColumnLayout(0, Qt::Vertical );
141   GroupButtons->layout()->setMargin( 0 ); GroupButtons->layout()->setSpacing( 0 ); 
142   QHBoxLayout* GroupButtonsLayout = new QHBoxLayout( GroupButtons->layout() );
143   GroupButtonsLayout->setAlignment( Qt::AlignTop );
144   GroupButtonsLayout->setMargin( 11 ); GroupButtonsLayout->setSpacing( 6 );
145   
146   buttonApply = new QPushButton( GroupButtons, "buttonApply" );
147   buttonApply->setText( tr( "BUT_APPLY"  ) );
148   buttonApply->setAutoDefault( TRUE ); 
149   buttonApply->setDefault( TRUE );
150   GroupButtonsLayout->addWidget( buttonApply );
151   
152   GroupButtonsLayout->addStretch();
153   
154   buttonClose = new QPushButton( GroupButtons, "buttonClose" );
155   buttonClose->setText( tr( "BUT_CLOSE"  ) );
156   buttonClose->setAutoDefault( TRUE );
157   GroupButtonsLayout->addWidget( buttonClose );
158   /***************************************************************/
159   
160   topLayout->addWidget( GroupPoint );
161   topLayout->addWidget( GroupDirection );
162   
163   topLayout->addWidget( PreviewChB );
164
165   topLayout->addWidget( GroupButtons );
166
167   /* initializations */
168
169   SpinBox_X->setValue( 0.0 );
170   SpinBox_Y->setValue( 0.0 );
171   SpinBox_Z->setValue( 0.0 );
172
173   SpinBox_Dx->setValue( 1.0 );
174   SpinBox_Dy->setValue( 1.0 );
175   SpinBox_Dz->setValue( 1.0 );
176
177   /* signals and slots connections */
178   connect( resetButton,  SIGNAL (clicked() ), this, SLOT( onReset() ) );
179   connect( invertButton, SIGNAL (clicked() ), this, SLOT( onInvert() ) ) ;
180
181   connect( SpinBox_X,  SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
182   connect( SpinBox_Y,  SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
183   connect( SpinBox_Z,  SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
184   connect( SpinBox_Dx, SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
185   connect( SpinBox_Dy, SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
186   connect( SpinBox_Dz, SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
187    
188   connect( DirectionCB, SIGNAL ( activated ( int ) ), this, SLOT( onModeChanged( int ) ) ) ;
189
190   connect( PreviewChB, SIGNAL ( toggled ( bool ) ), this, SLOT( onPreview( bool ) ) ) ;
191   
192   connect( buttonClose, SIGNAL( clicked() ), this, SLOT( ClickOnClose() ) ) ;
193   connect( buttonApply, SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
194   
195   myBusy = false;
196 }
197
198 //=================================================================================
199 // function : ~ OCCViewer_ClippingDlg()
200 // purpose  : Destroys the object and frees any allocated resources
201 //=================================================================================
202 OCCViewer_ClippingDlg::~ OCCViewer_ClippingDlg()
203 {
204   // no need to delete child widgets, Qt does it all for us
205 }
206
207
208 //=================================================================================
209 // function : closeEvent
210 // purpose  :
211 //=================================================================================
212 void OCCViewer_ClippingDlg::closeEvent( QCloseEvent* e )
213 {
214   erasePreview();
215   QDialog::closeEvent( e );
216 }
217
218
219 //=================================================================================
220 // function : showEvent
221 // purpose  :
222 //=================================================================================
223 void OCCViewer_ClippingDlg::showEvent( QShowEvent* e )
224 {
225   QDialog::showEvent( e );
226   onPreview( PreviewChB->isChecked() );
227 }
228
229
230 //=================================================================================
231 // function : hideEvent
232 // purpose  :
233 //=================================================================================
234 void OCCViewer_ClippingDlg::hideEvent( QHideEvent* e )
235 {
236   erasePreview();
237   QDialog::hideEvent( e );
238 }
239
240
241 //=================================================================================
242 // function : ClickOnClose()
243 // purpose  :
244 //=================================================================================
245 void OCCViewer_ClippingDlg::ClickOnClose()
246 {
247   erasePreview();
248   reject();
249 }
250
251
252 //=================================================================================
253 // function : ClickOnApply()
254 // purpose  :
255 //=================================================================================
256 void OCCViewer_ClippingDlg::ClickOnApply()
257 {
258   qApp->processEvents();
259   QApplication::setOverrideCursor( Qt::WaitCursor );
260   qApp->processEvents();
261   
262   myView->setCuttingPlane( true, SpinBox_X->value() , SpinBox_Y->value() , SpinBox_Z->value(),
263                                  SpinBox_Dx->value(), SpinBox_Dy->value(), SpinBox_Dz->value() );
264   
265   QApplication::restoreOverrideCursor(); 
266
267   erasePreview();
268 }
269
270
271 //=================================================================================
272 // function : onReset()
273 // purpose  :
274 //=================================================================================
275 void OCCViewer_ClippingDlg::onReset()
276 {
277   myBusy = true;
278   SpinBox_X->setValue(0);
279   SpinBox_Y->setValue(0);
280   SpinBox_Z->setValue(0);
281   myBusy = false;
282
283   if ( PreviewChB->isChecked() )
284     {
285       erasePreview();
286       displayPreview();
287     }
288 }
289
290
291 //=================================================================================
292 // function : onInvert()
293 // purpose  :
294 //=================================================================================
295 void OCCViewer_ClippingDlg::onInvert()
296 {
297   double Dx = SpinBox_Dx->value();
298   double Dy = SpinBox_Dy->value();
299   double Dz = SpinBox_Dz->value();
300   
301   myBusy = true;
302   SpinBox_Dx->setValue( -Dx );
303   SpinBox_Dy->setValue( -Dy );
304   SpinBox_Dz->setValue( -Dz );
305   myBusy = false;
306
307   if ( PreviewChB->isChecked() )
308     {
309       erasePreview();
310       displayPreview();
311     }
312 }
313
314
315 //=================================================================================
316 // function : onModeChanged()
317 // purpose  :
318 //=================================================================================
319 void OCCViewer_ClippingDlg::onModeChanged( int mode )
320 {
321   bool isUserMode = (mode==0);
322   
323   TextLabelX->setEnabled( isUserMode );
324   TextLabelY->setEnabled( isUserMode );
325   TextLabelZ->setEnabled( isUserMode );
326
327   SpinBox_X->setEnabled( isUserMode );
328   SpinBox_Y->setEnabled( isUserMode );
329   SpinBox_Z->setEnabled( isUserMode );
330
331   TextLabelDx->setEnabled( isUserMode );
332   TextLabelDy->setEnabled( isUserMode );
333   TextLabelDz->setEnabled( isUserMode );
334
335   SpinBox_Dx->setEnabled( isUserMode );
336   SpinBox_Dy->setEnabled( isUserMode );
337   SpinBox_Dz->setEnabled( isUserMode );
338   
339   if ( isUserMode )
340     return;
341
342   double aDx = 0, aDy = 0, aDz = 0;
343
344   if ( mode == 1 )
345     {
346       aDz = 1;
347       TextLabelZ->setEnabled( true );
348       SpinBox_Z->setEnabled( true );
349       SpinBox_Z->setFocus();
350     }
351   else if ( mode == 2 )
352     {
353       aDx = 1;
354       TextLabelX->setEnabled( true );
355       SpinBox_X->setEnabled( true );
356       SpinBox_X->setFocus();
357     }
358   else if ( mode == 3 )
359     {
360       aDy = 1;
361       TextLabelY->setEnabled( true );
362       SpinBox_Y->setEnabled( true );
363       SpinBox_Y->setFocus();
364     }
365   
366   myBusy = true;
367   SpinBox_Dx->setValue( aDx );
368   SpinBox_Dy->setValue( aDy );
369   SpinBox_Dz->setValue( aDz );
370   myBusy = false;
371
372   if ( PreviewChB->isChecked() )
373     {
374       erasePreview();
375       displayPreview();
376     }
377 }
378
379
380 //================================================================
381 // Function : displayPreview
382 // Purpose  : 
383 //================================================================
384 void OCCViewer_ClippingDlg::displayPreview()
385 {
386   if ( myBusy || !isValid() )
387     return;
388
389   OCCViewer_Viewer* anOCCViewer = (OCCViewer_Viewer*)myView->getViewManager()->getViewModel();
390   if (!anOCCViewer)
391     return;
392   
393   Handle(AIS_InteractiveContext) ic = anOCCViewer->getAISContext();
394
395   double aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;
396   aXMin = aYMin = aZMin = DBL_MAX;
397   aXMax = aYMax = aZMax = -DBL_MAX;
398
399   bool isFound = false;
400   AIS_ListOfInteractive aList;
401   ic->DisplayedObjects( aList );
402   for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() )
403   {
404     Handle(AIS_InteractiveObject) anObj = it.Value();
405     if ( !anObj.IsNull() && anObj->HasPresentation() &&
406          !anObj->IsKind( STANDARD_TYPE(AIS_Plane) ) )
407     {
408       Handle(Prs3d_Presentation) aPrs = anObj->Presentation();
409       if ( !aPrs->IsEmpty() && !aPrs->IsInfinite() )
410       {
411         isFound = true;
412         double xmin, ymin, zmin, xmax, ymax, zmax;
413         aPrs->MinMaxValues( xmin, ymin, zmin, xmax, ymax, zmax );
414         aXMin = QMIN( aXMin, xmin );  aXMax = QMAX( aXMax, xmax );
415         aYMin = QMIN( aYMin, ymin );  aYMax = QMAX( aYMax, ymax );
416         aZMin = QMIN( aZMin, zmin );  aZMax = QMAX( aZMax, zmax );
417       }
418     }
419   }
420
421   double aSize = 50;
422   
423   gp_Pnt aBasePnt( SpinBox_X->value(),  SpinBox_Y->value(),  SpinBox_Z->value() );
424   gp_Dir aNormal( SpinBox_Dx->value(), SpinBox_Dy->value(), SpinBox_Dz->value() );
425   gp_Pnt aCenter = aBasePnt;
426   
427   if ( isFound )
428     {
429       // compute clipping plane size
430       aCenter = gp_Pnt( ( aXMin + aXMax ) / 2, ( aYMin + aYMax ) / 2, ( aZMin + aZMax ) / 2 );
431       double aDiag = aCenter.Distance(gp_Pnt(aXMax, aYMax, aZMax ))*2;
432       aSize = aDiag * 1.1;
433
434       // compute clipping plane center ( redefine the base point )
435       IntAna_IntConicQuad intersector = IntAna_IntConicQuad();
436       
437       intersector.Perform( gp_Lin( aCenter, aNormal), gp_Pln( aBasePnt, aNormal), Precision::Confusion() );
438       if ( intersector.IsDone() && intersector.NbPoints() == 1 )
439         aBasePnt = intersector.Point( 1 );
440     }
441   
442   myPreviewPlane = new AIS_Plane( new Geom_Plane( aBasePnt, aNormal ) );
443   myPreviewPlane->SetSize( aSize, aSize );
444   
445   ic->Display( myPreviewPlane, 1, -1, false );
446   ic->SetWidth( myPreviewPlane, 10, false );
447   ic->SetMaterial( myPreviewPlane, Graphic3d_NOM_PLASTIC, false );
448   ic->SetTransparency( myPreviewPlane, 0.5, false );
449   ic->SetColor( myPreviewPlane, Quantity_Color( 85 / 255., 85 / 255., 255 / 255., Quantity_TOC_RGB ), false );
450   
451   anOCCViewer->update();
452 }
453
454
455 //================================================================
456 // Function : erasePreview
457 // Purpose  : 
458 //================================================================
459 void OCCViewer_ClippingDlg::erasePreview ()
460 {
461   OCCViewer_Viewer* anOCCViewer = (OCCViewer_Viewer*)myView->getViewManager()->getViewModel();
462   if (!anOCCViewer)
463     return;
464   
465   Handle(AIS_InteractiveContext) ic = anOCCViewer->getAISContext();
466   
467   if ( !myPreviewPlane.IsNull() && ic->IsDisplayed( myPreviewPlane ) )
468     {
469       ic->Erase( myPreviewPlane, false, false );
470       ic->Remove( myPreviewPlane, false );
471       myPreviewPlane.Nullify();
472     }
473   
474   anOCCViewer->update();
475 }
476
477
478 //================================================================
479 // Function : onValueChanged
480 // Purpose  : 
481 //================================================================
482 void OCCViewer_ClippingDlg::onValueChanged()
483 {
484   if ( PreviewChB->isChecked() )
485     {
486       erasePreview();
487       displayPreview();
488     }
489 }
490
491
492 //================================================================
493 // Function : onPreview
494 // Purpose  : 
495 //================================================================
496 void OCCViewer_ClippingDlg::onPreview( bool on )
497 {
498   erasePreview();
499
500   if ( on ) 
501     displayPreview();
502 }
503
504 //================================================================
505 // Function : onPreview
506 // Purpose  : 
507 //================================================================
508 bool OCCViewer_ClippingDlg::isValid()
509 {
510   return ( SpinBox_Dx->value()!=0 || SpinBox_Dy->value()!=0 || SpinBox_Dz->value()!=0 );
511 }