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