]> Creatis software - cpPlugins.git/blob - lib/cpPlugins/ActorPropertiesQtDialog.cxx
394c9081d885d3bd0d5c75b2544ce83639d908bf
[cpPlugins.git] / lib / cpPlugins / ActorPropertiesQtDialog.cxx
1 #include <cpPlugins/ActorPropertiesQtDialog.h>
2
3 #ifdef cpPlugins_QT4
4
5 #include <vtkActor.h>
6 #include <vtkAxesActor.h>
7 #include <vtkImageActor.h>
8 #include <vtkImageData.h>
9 #include <vtkImageProperty.h>
10 #include <vtkMapper.h>
11 #include <vtkProperty.h>
12
13 #include <QCheckBox>
14 #include <QColorDialog>
15 #include <QDoubleSpinBox>
16 #include <QPushButton>
17 #include <QSlider>
18
19 // -------------------------------------------------------------------------
20 cpPlugins::ActorPropertiesQtDialog::
21 ActorPropertiesQtDialog( QWidget* parent, Qt::WindowFlags f )
22   : QDialog( parent, f ),
23     m_WidgetsUpdated( false )
24 {
25   this->m_Title = new QLabel( this );
26   this->m_Title->setText( "Visualization properties" );
27   this->m_MainLayout = new QGridLayout( this );
28   this->m_ToolsLayout = new QVBoxLayout( );
29   this->m_ToolsLayout->addWidget( this->m_Title );
30   this->m_MainLayout->addLayout( this->m_ToolsLayout, 0, 0, 1, 1 );
31 }
32
33 // -------------------------------------------------------------------------
34 cpPlugins::ActorPropertiesQtDialog::
35 ~ActorPropertiesQtDialog( )
36 {
37   this->m_Actors.clear( );
38   this->m_Windows.clear( );
39   delete this->m_Title;
40   delete this->m_ToolsLayout;
41   delete this->m_MainLayout;
42 }
43
44 // -------------------------------------------------------------------------
45 bool cpPlugins::ActorPropertiesQtDialog::
46 addActor( vtkProp* obj )
47 {
48   if( obj == NULL )
49     return( false );
50
51   if( this->m_Actors.size( ) > 0 )
52   {
53     bool     s = this->_addActor< vtkAxesActor >( obj );
54     if( !s ) s = this->_addActor< vtkImageActor >( obj );
55     if( !s ) s = this->_addActor< vtkActor >( obj );
56     return( s );
57   }
58   else
59   {
60     this->m_Actors.insert( obj );
61     this->m_WidgetsUpdated = false;
62     return( true );
63
64   } // fi
65 }
66
67 // -------------------------------------------------------------------------
68 bool cpPlugins::ActorPropertiesQtDialog::
69 addRenderWindow( vtkRenderWindow* win )
70 {
71   if( win == NULL )
72     return( false );
73   this->m_Windows.insert( win );
74   this->m_WidgetsUpdated = false;
75   return( true );
76 }
77
78 // -------------------------------------------------------------------------
79 int cpPlugins::ActorPropertiesQtDialog::
80 exec( )
81 {
82   this->_updateWidgets( );
83   int ret = this->QDialog::exec( );
84   /* TODO
85      if( ret == 1 )
86      this->updateParameters( );
87      else
88      this->updateView( );
89   */
90   return( ret );
91 }
92
93 // -------------------------------------------------------------------------
94 void cpPlugins::ActorPropertiesQtDialog::
95 _addButtons( )
96 {
97   // Add buttons
98   this->m_Buttons = new QDialogButtonBox( QDialogButtonBox::Ok );
99   this->connect(
100     this->m_Buttons, SIGNAL( accepted( ) ), this, SLOT( accept( ) )
101     );
102   this->connect(
103     this->m_Buttons, SIGNAL( rejected( ) ), this, SLOT( reject( ) )
104     );
105   this->m_ToolsLayout->addWidget( this->m_Buttons );
106   this->m_WidgetsUpdated = true;
107 }
108
109 // -------------------------------------------------------------------------
110 void cpPlugins::ActorPropertiesQtDialog::
111 _updateWidgets( )
112 {
113   if( this->m_WidgetsUpdated || this->m_Actors.size( ) == 0 )
114     return;
115   bool     s = this->_configureForAxes( );
116   if( !s ) s = this->_configureForImage( );
117   if( !s ) s = this->_configureForMesh( );
118   this->_addButtons( );
119 }
120
121 // -------------------------------------------------------------------------
122 bool cpPlugins::ActorPropertiesQtDialog::
123 _configureForAxes( )
124 {
125   if( this->m_Actors.size( ) == 0 )
126     return( false );
127   auto actor =
128     dynamic_cast< vtkAxesActor* >( this->m_Actors.begin( )->GetPointer( ) );
129   if( actor == NULL )
130     return( false );
131
132   // Set dialog title
133   std::stringstream title;
134   title << "Parameters for an object of class \"Axes\"";
135   this->m_Title->setText( title.str( ).c_str( ) );
136
137   return( true );
138 }
139
140 // -------------------------------------------------------------------------
141 bool cpPlugins::ActorPropertiesQtDialog::
142 _configureForImage( )
143 {
144   if( this->m_Actors.size( ) == 0 )
145     return( false );
146   auto actor =
147     dynamic_cast< vtkImageActor* >( this->m_Actors.begin( )->GetPointer( ) );
148   if( actor == NULL )
149     return( false );
150   auto image = actor->GetInput( );
151   if( image == NULL )
152     return( false );
153
154   // Get properties
155   auto prop = actor->GetProperty( );
156   double r[ 2 ];
157   image->GetScalarRange( r );
158   double w = actor->GetProperty( )->GetColorWindow( );
159   double l = actor->GetProperty( )->GetColorLevel( );
160   double sw = double( 1000 ) * w / ( r[ 1 ] - r[ 0 ] );
161   double sl = double( 1000 ) * ( l - r[ 0 ] ) / ( r[ 1 ] - r[ 0 ] );
162   double op = double( 10 ) * prop->GetOpacity( );
163
164   // Set dialog title
165   std::stringstream title;
166   title << "Parameters for an object of class \"Image\"";
167   this->m_Title->setText( title.str( ).c_str( ) );
168
169   // Create widgets
170   QDoubleSpinBox* win_box = new QDoubleSpinBox( this );
171   win_box->setObjectName( "win_box" );
172   win_box->setDecimals( 3 );
173   win_box->setMinimum( 0 );
174   win_box->setMaximum( r[ 1 ] - r[ 0 ] );
175   win_box->setValue( w );
176   win_box->connect(
177     win_box, SIGNAL( valueChanged( double ) ),
178     this, SLOT( _boxWindow( double ) )
179     );
180
181   QSlider* win_sld = new QSlider( Qt::Horizontal, this );
182   win_sld->setObjectName( "win_sld" );
183   win_sld->setRange( 0, 1000 );
184   win_sld->setValue( ( unsigned int )( sw ) );
185   win_sld->connect(
186     win_sld, SIGNAL( valueChanged( int ) ),
187     this, SLOT( _sldWindow( int ) )
188     );
189
190   QHBoxLayout* win_layout = new QHBoxLayout( );
191   QLabel* win_label = new QLabel( this );
192   win_label->setText( QString( "Window: " ) );
193   win_layout->addWidget( win_label );
194   win_layout->addWidget( win_box );
195   win_layout->addWidget( win_sld );
196   this->m_ToolsLayout->addLayout( win_layout );
197
198   QDoubleSpinBox* lev_box = new QDoubleSpinBox( this );
199   lev_box->setObjectName( "lev_box" );
200   lev_box->setDecimals( 3 );
201   lev_box->setMinimum( r[ 0 ] );
202   lev_box->setMaximum( r[ 1 ] );
203   lev_box->setValue( l );
204   lev_box->connect(
205     lev_box, SIGNAL( valueChanged( double ) ),
206     this, SLOT( _boxLevel( double ) )
207     );
208
209   QSlider* lev_sld = new QSlider( Qt::Horizontal, this );
210   lev_sld->setObjectName( "lev_sld" );
211   lev_sld->setRange( 0, 1000 );
212   lev_sld->setValue( ( unsigned int )( sl ) );
213   lev_sld->connect(
214     lev_sld, SIGNAL( valueChanged( int ) ),
215     this, SLOT( _sldLevel( int ) )
216     );
217
218   QHBoxLayout* lev_layout = new QHBoxLayout( );
219   QLabel* lev_label = new QLabel( this );
220   lev_label->setText( QString( "Level: " ) );
221   lev_layout->addWidget( lev_label );
222   lev_layout->addWidget( lev_box );
223   lev_layout->addWidget( lev_sld );
224   this->m_ToolsLayout->addLayout( lev_layout );
225
226   // Configure generic objects
227   QSlider* op_sld = new QSlider( Qt::Horizontal, this );
228   op_sld->setObjectName( "op_sld" );
229   op_sld->setRange( 0, 10 );
230   op_sld->setValue( ( unsigned int )( op ) );
231   op_sld->connect(
232     op_sld, SIGNAL( valueChanged( int ) ),
233     this, SLOT( _sldOpacity( int ) )
234     );
235
236   QHBoxLayout* op_layout = new QHBoxLayout( );
237   QLabel* op_label = new QLabel( this );
238   op_label->setText( QString( "Opacity: " ) );
239   op_layout->addWidget( op_label );
240   op_layout->addWidget( op_sld );
241   this->m_ToolsLayout->addLayout( op_layout );
242
243   return( true );
244 }
245
246 // -------------------------------------------------------------------------
247 bool cpPlugins::ActorPropertiesQtDialog::
248 _configureForMesh( )
249 {
250   if( this->m_Actors.size( ) == 0 )
251     return( false );
252   auto actor =
253     dynamic_cast< vtkActor* >( this->m_Actors.begin( )->GetPointer( ) );
254   if( actor == NULL )
255     return( false );
256   auto prop = actor->GetProperty( );
257
258   // Set dialog title
259   std::stringstream title;
260   title << "Parameters for an object of class \"Mesh\"";
261   this->m_Title->setText( title.str( ).c_str( ) );
262
263   // Input boxes
264   QSpinBox* ps_box = new QSpinBox( this );
265   ps_box->setObjectName( "ps_box" );
266   ps_box->setMinimum( 1 );
267   ps_box->setMaximum( 100 );
268   ps_box->setValue( prop->GetPointSize( ) );
269   ps_box->connect(
270     ps_box, SIGNAL( valueChanged( int ) ),
271     this, SLOT( _boxPointSize( int ) )
272     );
273
274   QHBoxLayout* ps_layout = new QHBoxLayout( );
275   QLabel* ps_label = new QLabel( this );
276   ps_label->setText( QString( "Point size: " ) );
277   ps_layout->addWidget( ps_label );
278   ps_layout->addWidget( ps_box );
279   this->m_ToolsLayout->addLayout( ps_layout );
280
281   QSpinBox* lw_box = new QSpinBox( this );
282   lw_box->setObjectName( "lw_box" );
283   lw_box->setMinimum( 1 );
284   lw_box->setMaximum( 100 );
285   lw_box->setValue( prop->GetLineWidth( ) );
286   lw_box->connect(
287     lw_box, SIGNAL( valueChanged( int ) ),
288     this, SLOT( _boxLineWidth( int ) )
289     );
290
291   QHBoxLayout* lw_layout = new QHBoxLayout( );
292   QLabel* lw_label = new QLabel( this );
293   lw_label->setText( QString( "Line width: " ) );
294   lw_layout->addWidget( lw_label );
295   lw_layout->addWidget( lw_box );
296   this->m_ToolsLayout->addLayout( lw_layout );
297
298   QCheckBox* sv_box = new QCheckBox( this );
299   sv_box->setObjectName( "sv_box" );
300   sv_box->setText( "Scalar visibility: " );
301   sv_box->setChecked( ( actor->GetMapper( )->GetScalarVisibility( ) == 1 ) );
302   sv_box->connect(
303     sv_box, SIGNAL( stateChanged( int ) ),
304     this, SLOT( _scalarVisibility( int ) )
305     );
306
307   QHBoxLayout* sv_layout = new QHBoxLayout( );
308   sv_layout->addWidget( sv_box );
309   this->m_ToolsLayout->addLayout( sv_layout );
310
311   double cr, cg, cb;
312   prop->GetColor( cr, cg, cb );
313   cr *= double( 255 );
314   cg *= double( 255 );
315   cb *= double( 255 );
316
317   QPushButton* color_button = new QPushButton( "Color", this );
318   color_button->setObjectName( "color_button" );
319   QPalette color_palette = color_button->palette( );
320   color_palette.setColor( QPalette::Button, QColor( cr, cg, cb ) );
321   color_button->setAutoFillBackground( true );
322   color_button->setPalette( color_palette );
323   color_button->update( );
324   color_button->connect(
325     color_button, SIGNAL( clicked( ) ),
326     this, SLOT( _color( ) )
327     );
328
329   QHBoxLayout* color_layout = new QHBoxLayout( );
330   color_layout->addWidget( color_button );
331   this->m_ToolsLayout->addLayout( color_layout );
332
333   // Configure generic objects
334   QSlider* op_sld = new QSlider( Qt::Horizontal, this );
335   op_sld->setObjectName( "op_sld" );
336   op_sld->setRange( 0, 10 );
337   op_sld->setValue(
338     ( unsigned int )( prop->GetOpacity( ) * double( 10 ) )
339     );
340   op_sld->connect(
341     op_sld, SIGNAL( valueChanged( int ) ),
342     this, SLOT( _sldOpacity( int ) )
343     );
344
345   QHBoxLayout* op_layout = new QHBoxLayout( );
346   QLabel* op_label = new QLabel( this );
347   op_label->setText( QString( "Opacity: " ) );
348   op_layout->addWidget( op_label );
349   op_layout->addWidget( op_sld );
350   this->m_ToolsLayout->addLayout( op_layout );
351
352   return( true );
353 }
354
355 // -------------------------------------------------------------------------
356 void cpPlugins::ActorPropertiesQtDialog::
357 _setWindow( double w )
358 {
359   if( this->m_Actors.size( ) == 0 )
360     return;
361   auto aIt = this->m_Actors.begin( );
362   for( ; aIt != this->m_Actors.end( ); ++aIt )
363   {
364     auto actor = dynamic_cast< vtkImageActor* >( aIt->GetPointer( ) );
365     if( actor != NULL )
366     {
367       actor->GetProperty( )->SetColorWindow( w );
368       actor->Modified( );
369
370     } // fi
371
372   } // rof
373   this->_render( );
374 }
375
376 // -------------------------------------------------------------------------
377 void cpPlugins::ActorPropertiesQtDialog::
378 _setLevel( double l )
379 {
380   if( this->m_Actors.size( ) == 0 )
381     return;
382   auto aIt = this->m_Actors.begin( );
383   for( ; aIt != this->m_Actors.end( ); ++aIt )
384   {
385     auto actor = dynamic_cast< vtkImageActor* >( aIt->GetPointer( ) );
386     if( actor != NULL )
387     {
388       actor->GetProperty( )->SetColorLevel( l );
389       actor->Modified( );
390
391     } // fi
392
393   } // rof
394   this->_render( );
395 }
396
397 // -------------------------------------------------------------------------
398 void cpPlugins::ActorPropertiesQtDialog::
399 _render( )
400 {
401   for( auto i = this->m_Windows.begin( ); i != this->m_Windows.end( ); ++i )
402     ( *i )->Render( );
403 }
404
405 // -------------------------------------------------------------------------
406 template< class _TActor >
407 bool cpPlugins::ActorPropertiesQtDialog::
408 _addActor( vtkProp* obj )
409 {
410   auto new_obj = dynamic_cast< _TActor* >( obj );
411   auto pre_obj =
412     dynamic_cast< _TActor* >( this->m_Actors.begin( )->GetPointer( ) );
413   if( new_obj != NULL && pre_obj != NULL )
414   {
415     this->m_Actors.insert( obj );
416     this->m_WidgetsUpdated = false;
417     return( true );
418   }
419   else
420     return( false );
421 }
422
423 // -------------------------------------------------------------------------
424 void cpPlugins::ActorPropertiesQtDialog::
425 _boxWindow( double v )
426 {
427   auto* box = this->findChild< QDoubleSpinBox* >( "win_box" );
428   auto* sld = this->findChild< QSlider* >( "win_sld" );
429   if( box == NULL || sld == NULL )
430     return;
431
432   double min = double( sld->minimum( ) );
433   double max = double( sld->maximum( ) );
434   double vmin = box->minimum( );
435   double vmax = box->maximum( );
436   double s = ( v - vmin ) / ( vmax - vmin );
437   s = ( ( max - min ) * s ) + min;
438
439   bool o = sld->blockSignals( true );
440   sld->setValue( ( unsigned int )( s ) );
441   sld->blockSignals( o );
442   this->_setWindow( v );
443 }
444
445 // -------------------------------------------------------------------------
446 void cpPlugins::ActorPropertiesQtDialog::
447 _sldWindow( int v )
448 {
449   auto* box = this->findChild< QDoubleSpinBox* >( "win_box" );
450   auto* sld = this->findChild< QSlider* >( "win_sld" );
451   if( box == NULL || sld == NULL )
452     return;
453
454   double min = double( sld->minimum( ) );
455   double max = double( sld->maximum( ) );
456   double vmin = box->minimum( );
457   double vmax = box->maximum( );
458   double s = ( double( v ) - min ) / ( max - min );
459   s = ( ( vmax - vmin ) * s ) + vmin;
460
461   bool o = box->blockSignals( true );
462   box->setValue( s );
463   box->blockSignals( o );
464   this->_setWindow( s );
465 }
466
467 // -------------------------------------------------------------------------
468 void cpPlugins::ActorPropertiesQtDialog::
469 _boxLevel( double v )
470 {
471   auto* box = this->findChild< QDoubleSpinBox* >( "lev_box" );
472   auto* sld = this->findChild< QSlider* >( "lev_sld" );
473   if( box == NULL || sld == NULL )
474     return;
475
476   double min = double( sld->minimum( ) );
477   double max = double( sld->maximum( ) );
478   double vmin = box->minimum( );
479   double vmax = box->maximum( );
480   double s = ( v - vmin ) / ( vmax - vmin );
481   s = ( ( max - min ) * s ) + min;
482
483   bool o = sld->blockSignals( true );
484   sld->setValue( ( unsigned int )( s ) );
485   sld->blockSignals( o );
486   this->_setLevel( v );
487 }
488
489 // -------------------------------------------------------------------------
490 void cpPlugins::ActorPropertiesQtDialog::
491 _sldLevel( int v )
492 {
493   auto* box = this->findChild< QDoubleSpinBox* >( "lev_box" );
494   auto* sld = this->findChild< QSlider* >( "lev_sld" );
495   if( box == NULL || sld == NULL )
496     return;
497
498   double min = double( sld->minimum( ) );
499   double max = double( sld->maximum( ) );
500   double vmin = box->minimum( );
501   double vmax = box->maximum( );
502   double s = ( double( v ) - min ) / ( max - min );
503   s = ( ( vmax - vmin ) * s ) + vmin;
504
505   bool o = box->blockSignals( true );
506   box->setValue( s );
507   box->blockSignals( o );
508   this->_setLevel( s );
509 }
510
511 // -------------------------------------------------------------------------
512 void cpPlugins::ActorPropertiesQtDialog::
513 _sldOpacity( int v )
514 {
515   if( this->m_Actors.size( ) == 0 )
516     return;
517   auto* sld = this->findChild< QSlider* >( "op_sld" );
518   if( sld == NULL )
519     return;
520
521   double min = double( sld->minimum( ) );
522   double max = double( sld->maximum( ) );
523   double s = ( double( v ) - min ) / ( max - min );
524
525   auto aIt = this->m_Actors.begin( );
526   for( ; aIt != this->m_Actors.end( ); ++aIt )
527   {
528     auto ia = dynamic_cast< vtkImageActor* >( aIt->GetPointer( ) );
529     auto ma = dynamic_cast< vtkActor* >( aIt->GetPointer( ) );
530     if( ia != NULL )
531     {
532       ia->GetProperty( )->SetOpacity( s );
533       ia->Modified( );
534     }
535     else if( ma != NULL )
536     {
537       ma->GetProperty( )->SetOpacity( s );
538       ma->Modified( );
539
540     } // fi
541
542   } // rof
543   this->_render( );
544 }
545
546 // -------------------------------------------------------------------------
547 void cpPlugins::ActorPropertiesQtDialog::
548 _boxPointSize( int v )
549 {
550   if( this->m_Actors.size( ) == 0 )
551     return;
552   auto aIt = this->m_Actors.begin( );
553   for( ; aIt != this->m_Actors.end( ); ++aIt )
554   {
555     auto ma = dynamic_cast< vtkActor* >( aIt->GetPointer( ) );
556     if( ma != NULL )
557     {
558       ma->GetProperty( )->SetPointSize( v );
559       ma->Modified( );
560
561     } // fi
562
563   } // rof
564   this->_render( );
565 }
566
567 // -------------------------------------------------------------------------
568 void cpPlugins::ActorPropertiesQtDialog::
569 _boxLineWidth( int v )
570 {
571   if( this->m_Actors.size( ) == 0 )
572     return;
573   auto aIt = this->m_Actors.begin( );
574   for( ; aIt != this->m_Actors.end( ); ++aIt )
575   {
576     auto ma = dynamic_cast< vtkActor* >( aIt->GetPointer( ) );
577     if( ma != NULL )
578     {
579       ma->GetProperty( )->SetLineWidth( v );
580       ma->Modified( );
581
582     } // fi
583
584   } // rof
585   this->_render( );
586 }
587
588 // -------------------------------------------------------------------------
589 void cpPlugins::ActorPropertiesQtDialog::
590 _scalarVisibility( int v )
591 {
592   if( this->m_Actors.size( ) == 0 )
593     return;
594   auto* btn = this->findChild< QPushButton* >( "color_button" );
595   auto* chk = this->findChild< QCheckBox* >( "sv_box" );
596   if( btn == NULL || chk == NULL )
597     return;
598   QPalette pal = btn->palette( );
599   QColor color = pal.color( QPalette::Button );
600   double rgb[ 3 ];
601   rgb[ 0 ] = double( color.red( ) ) / double( 255 );
602   rgb[ 1 ] = double( color.green( ) ) / double( 255 );
603   rgb[ 2 ] = double( color.blue( ) ) / double( 255 );
604
605   auto aIt = this->m_Actors.begin( );
606   for( ; aIt != this->m_Actors.end( ); ++aIt )
607   {
608     auto ma = dynamic_cast< vtkActor* >( aIt->GetPointer( ) );
609     if( ma != NULL )
610     {
611       if( !( chk->isChecked( ) ) )
612       {
613         ma->GetMapper( )->ScalarVisibilityOff( );
614         ma->GetProperty( )->SetColor( rgb );
615       }
616       else
617         ma->GetMapper( )->ScalarVisibilityOn( );
618       ma->Modified( );
619
620     } // fi
621
622   } // rof
623   this->_render( );
624 }
625
626 // -------------------------------------------------------------------------
627 void cpPlugins::ActorPropertiesQtDialog::
628 _color( )
629 {
630   if( this->m_Actors.size( ) == 0 )
631     return;
632   auto* btn = this->findChild< QPushButton* >( "color_button" );
633   auto* chk = this->findChild< QCheckBox* >( "sv_box" );
634   if( btn == NULL || chk == NULL )
635     return;
636
637   QPalette pal = btn->palette( );
638   QColor color =
639     QColorDialog::getColor(
640       pal.color( QPalette::Button ),
641       this,
642       "Select Color",
643       QColorDialog::DontUseNativeDialog
644       );
645   if( color.isValid( ) )
646   {
647     pal.setColor( QPalette::Button, color );
648     btn->setAutoFillBackground( true );
649     btn->setPalette( pal );
650     btn->update( );
651     this->_scalarVisibility( 0 );
652
653   } // fi
654 }
655
656 #endif // cpPlugins_QT4
657
658 // eof - $RCSfile$