[vtkusers] Subclassing vtkInteractorStyle in FourPainView Example

Alex Malyushytskyy alexmalvtk at gmail.com
Wed Sep 11 20:41:10 EDT 2013


>> The major changes compared to the original code is the inclusion in
QtVTKRenderWindows.cxx of the subclass KeyPressInteractorStyle and the 3
lines of code where I apply the new style to view1. Both of these changes
were included in my first post.

The code you posted originally  did not really provide enough information.
Where it was placed, etc.
Also if I had your code in attachment it would save me time.

Back to your code. You are setting style, then redefine render window ,
change interactor etc.
To fix it:

a) Create instance of KeyPressInteractorStyle per view and replace

vtkSmartPointer<KeyPressInteractorStyle> style =
vtkSmartPointer<KeyPressInteractorStyle>::New();

with

  vtkSmartPointer<KeyPressInteractorStyle> style1 =
vtkSmartPointer<KeyPressInteractorStyle>::New();
  vtkSmartPointer<KeyPressInteractorStyle> style2 =
vtkSmartPointer<KeyPressInteractorStyle>::New();
  vtkSmartPointer<KeyPressInteractorStyle> style3 =
vtkSmartPointer<KeyPressInteractorStyle>::New();
  vtkSmartPointer<KeyPressInteractorStyle> style4 =
vtkSmartPointer<KeyPressInteractorStyle>::New();


b) remove all your changes related to applying style.


this->ui->view1->GetInteractor()->SetInteractorStyle(style);

//this->ui->view1->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style);
//this->ui->view1->GetRenderWindow()->AddRenderer(riw[0]->GetRenderer());
 style->SetCurrentRenderer(riw[0]->GetRenderer());


c) Insert


this->ui->view1->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style1);

this->ui->view2->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style2);

this->ui->view3->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style3);

this->ui->view4->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style4);

before

  this->ui->view1->show();
  this->ui->view2->show();
  this->ui->view3->show()


You will see output messages for every of 4 views when you click buttons
there.

Regards,
    Alex

On Wed, Sep 11, 2013 at 3:23 AM, Panayiotis Georgiou
<ps.georgiou at gmail.com>wrote:

> Hello,
>
> I am essentially trying to build on the FourPaneViewer example which you
> can find from here:
> https://github.com/Kitware/VTK/tree/master/Examples/GUI/Qt/FourPaneViewer
>
> The major changes compared to the original code is the inclusion in
> QtVTKRenderWindows.cxx of the subclass KeyPressInteractorStyle and the 3
> lines of code where I apply the new style to view1. Both of these changes
> were included in my first post.
>
> Below I have including the code I am using which consists of 3 files: QtVTKRenderWindows.cxx, QtVTKRenderWindows.h
> and QtVTKRenderWindowsApp.cxx
>
> You can download the .ui file from the above link.
>
> Note: you may want to change the path to the Dicom files at
> reader->SetDirectoryName(...)
>
> Thanks for your help.
>
> ==================
> QtVTKRenderWindows.h
> ==================
>
> #ifndef QtVTKRenderWindows_H
> #define QtVTKRenderWindows_H
>
> #include "vtkSmartPointer.h"
> #include "vtkResliceImageViewer.h"
> #include "vtkImagePlaneWidget.h"
> #include "vtkDistanceWidget.h"
> #include "vtkResliceImageViewerMeasurements.h"
> #include <QMainWindow>
>
> // Forward Qt class declarations
> class Ui_QtVTKRenderWindows;
>
> class QtVTKRenderWindows : public QMainWindow
> {
>   Q_OBJECT
> public:
>
>   // Constructor/Destructor
>   QtVTKRenderWindows(int argc, char *argv[]);
>   ~QtVTKRenderWindows() {};
>
> public slots:
>   virtual void resliceMode(int);
>   virtual void Render();
>
> protected:
>   vtkSmartPointer< vtkResliceImageViewer > riw[3];
>   vtkSmartPointer< vtkImagePlaneWidget > planeWidget[3];
>   vtkSmartPointer< vtkDistanceWidget > DistanceWidget[3];
>   vtkSmartPointer< vtkResliceImageViewerMeasurements > ResliceMeasurements;
>
> private:
>
>   // Designer form
>   Ui_QtVTKRenderWindows *ui;
> };
>
> #endif // QtVTKRenderWindows_H
>
> ====================
> QtVTKRenderWindows.cxx
> ====================
>
> #include "ui_QtVTKRenderWindows.h"
> #include "QtVTKRenderWindows.h"
>
> #include <vtkRenderer.h>
> #include <vtkRenderWindow.h>
> #include "vtkResliceImageViewer.h"
> #include "vtkResliceCursorLineRepresentation.h"
> #include "vtkResliceCursorThickLineRepresentation.h"
> #include "vtkResliceCursorWidget.h"
> #include "vtkResliceCursorActor.h"
> #include "vtkResliceCursorPolyDataAlgorithm.h"
> #include "vtkResliceCursor.h"
> #include "vtkDICOMImageReader.h"
> #include "vtkCellPicker.h"
> #include "vtkProperty.h"
> #include "vtkPlane.h"
> #include "vtkImageData.h"
> #include "vtkCommand.h"
> #include "vtkPlaneSource.h"
> #include "vtkLookupTable.h"
> #include "vtkImageMapToWindowLevelColors.h"
> #include "vtkInteractorStyleImage.h"
> #include "vtkImageSlabReslice.h"
> #include "vtkBoundedPlanePointPlacer.h"
> #include "vtkDistanceWidget.h"
> #include "vtkDistanceRepresentation.h"
> #include "vtkHandleRepresentation.h"
> #include "vtkResliceImageViewerMeasurements.h"
> #include "vtkDistanceRepresentation2D.h"
> #include "vtkPointHandleRepresentation3D.h"
> #include "vtkPointHandleRepresentation2D.h"
> #include <qdebug.h>
>
> #include <vtkPolyDataMapper.h>
> #include <vtkObjectFactory.h>
> #include <vtkActor.h>
> #include <vtkSmartPointer.h>
> #include <vtkRenderWindow.h>
> #include <vtkRenderer.h>
> #include <vtkRenderWindowInteractor.h>
> #include <vtkPolyData.h>
> #include <vtkSphereSource.h>
> #include <vtkInteractorStyleTrackballCamera.h>
> #include "QVTKWidget.h"
> #include <QKeyEvent>
>
> // Define interaction style
> class KeyPressInteractorStyle : public vtkInteractorStyle
> {
> public:
> static KeyPressInteractorStyle* New();
>  vtkTypeMacro(KeyPressInteractorStyle, vtkInteractorStyle);
>
> virtual void OnKeyPress()
>  {
> // Get the keypress
> vtkRenderWindowInteractor *rwi = this->Interactor;
>  std::string key = rwi->GetKeySym();
>
> // Output the key that was pressed
>  std::cout << "Pressed " << key << std::endl;
> qDebug()<< "Pressed " << rwi->GetKeySym();
>
> // Forward events
> vtkInteractorStyle::OnKeyPress();
>  }
>
> virtual void OnChar()
>  {
>
> qDebug()<<"keeeey";
>  }
>
> };
> vtkStandardNewMacro(KeyPressInteractorStyle);
>
>
>
> //----------------------------------------------------------------------------
> class vtkResliceCursorCallback : public vtkCommand
> {
> public:
>
>  static vtkResliceCursorCallback *New()
> {
>  return new vtkResliceCursorCallback; }
>
> void Execute( vtkObject *caller, unsigned long ev,
>  void *callData )
> {
>
>  if (ev == vtkCommand::KeyPressEvent)
> {
>  QKeyEvent* keyPressed = static_cast<QKeyEvent*>(callData);
>  qDebug()<<"key pressed: "<<keyPressed->text();
> }
>
> if (ev == vtkResliceCursorWidget::WindowLevelEvent ||
> ev == vtkCommand::WindowLevelEvent ||
>  ev == vtkResliceCursorWidget::ResliceThicknessChangedEvent||
> ev == vtkResliceCursorWidget::ResliceAxesChangedEvent||
>  ev == vtkResliceCursorWidget::ResetCursorEvent)
> {
>  //do nothing
> }
>
>  vtkImagePlaneWidget* ipw =
> dynamic_cast< vtkImagePlaneWidget* >( caller );
>  if (ipw)
> {
> double* wl = static_cast<double*>( callData );
>
> if ( ipw == this->IPW[0] )
> {
>
> this->IPW[1]->SetWindowLevel(wl[0],wl[1],1);
> this->IPW[2]->SetWindowLevel(wl[0],wl[1],1);
>
> }
> else if( ipw == this->IPW[1] )
>  {
> this->IPW[0]->SetWindowLevel(wl[0],wl[1],1);
>  this->IPW[2]->SetWindowLevel(wl[0],wl[1],1);
> }
>  else if (ipw == this->IPW[2])
> {
>  this->IPW[0]->SetWindowLevel(wl[0],wl[1],1);
> this->IPW[1]->SetWindowLevel(wl[0],wl[1],1);
>  }
> }
>
>  vtkResliceCursorWidget *rcw = dynamic_cast<
> vtkResliceCursorWidget * >(caller);
>  if (rcw)
> {
> vtkResliceCursorLineRepresentation *rep = dynamic_cast<
>  vtkResliceCursorLineRepresentation * >(rcw->GetRepresentation());
> // Although the return value is not used, we keep the get calls
>  // in case they had side-effects
> rep->GetResliceCursorActor()->GetCursorAlgorithm()->GetResliceCursor();
>  for (int i = 0; i < 3; i++)
> {
>  vtkPlaneSource *ps = static_cast< vtkPlaneSource * >(
> this->IPW[i]->GetPolyDataAlgorithm());
>  ps->SetOrigin(this->RCW[i]->GetResliceCursorRepresentation()->
> GetPlaneSource()->GetOrigin());
>  ps->SetPoint1(this->RCW[i]->GetResliceCursorRepresentation()->
> GetPlaneSource()->GetPoint1());
>  ps->SetPoint2(this->RCW[i]->GetResliceCursorRepresentation()->
> GetPlaneSource()->GetPoint2());
>
> // If the reslice plane has modified, update it on the 3D widget
>  this->IPW[i]->UpdatePlacement();
> }
>  }
>
> if(ev == vtkResliceImageViewer::SliceChangedEvent)
>  {
> for (int i = 0; i < 3; i++)
>  {
> vtkPlaneSource *ps = static_cast< vtkPlaneSource * >(
>  this->IPW[i]->GetPolyDataAlgorithm());
> ps->SetOrigin(this->RCW[i]->GetResliceCursorRepresentation()->
>  GetPlaneSource()->GetOrigin());
> ps->SetPoint1(this->RCW[i]->GetResliceCursorRepresentation()->
>  GetPlaneSource()->GetPoint1());
> ps->SetPoint2(this->RCW[i]->GetResliceCursorRepresentation()->
>  GetPlaneSource()->GetPoint2());
>
> // If the reslice plane has modified, update it on the 3D widget
>  this->IPW[i]->UpdatePlacement();
> }
>  }
>
> // Render everything
>  for (int i = 0; i < 3; i++)
> {
>  this->RCW[i]->Render();
> }
>  this->IPW[0]->GetInteractor()->GetRenderWindow()->Render();
> }
>
> vtkResliceCursorCallback() {}
> vtkImagePlaneWidget* IPW[3];
>  vtkResliceCursorWidget *RCW[3];
> };
>
>
> QtVTKRenderWindows::QtVTKRenderWindows( int vtkNotUsed(argc), char *argv[])
> {
>  this->ui = new Ui_QtVTKRenderWindows;
> this->ui->setupUi(this);
>
> vtkSmartPointer< vtkDICOMImageReader > reader =
> vtkSmartPointer< vtkDICOMImageReader >::New();
>  //reader->SetDirectoryName(argv[1]);
>
> reader->SetDirectoryName("C:/Users/Panayiotis/DentalCEsse/qt_interface/build/Release/temp_dental/2/dicom");
>  reader->Update();
> int imageDims[3];
>  reader->GetOutput()->GetDimensions(imageDims);
>
>
>  for (int i = 0; i < 3; i++)
> {
>  riw[i] = vtkSmartPointer< vtkResliceImageViewer >::New();
> }
>
> vtkSmartPointer<KeyPressInteractorStyle> style =
> vtkSmartPointer<KeyPressInteractorStyle>::New();
>
> this->ui->view1->GetInteractor()->SetInteractorStyle(style);
>
> //this->ui->view1->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style);
> //this->ui->view1->GetRenderWindow()->AddRenderer(riw[0]->GetRenderer());
>  style->SetCurrentRenderer(riw[0]->GetRenderer());
>
> this->ui->view1->SetRenderWindow(riw[0]->GetRenderWindow());
>  riw[0]->SetupInteractor(
> this->ui->view1->GetRenderWindow()->GetInteractor());
>  this->ui->view2->SetRenderWindow(riw[1]->GetRenderWindow());
>  riw[1]->SetupInteractor(
> this->ui->view2->GetRenderWindow()->GetInteractor());
>
> this->ui->view3->SetRenderWindow(riw[2]->GetRenderWindow());
>  riw[2]->SetupInteractor(
> this->ui->view3->GetRenderWindow()->GetInteractor());
>
> for (int i = 0; i < 3; i++)
> {
>  // make them all share the same reslice cursor object.
> vtkResliceCursorLineRepresentation *rep =
>  vtkResliceCursorLineRepresentation::SafeDownCast(
> riw[i]->GetResliceCursorWidget()->GetRepresentation());
>  riw[i]->SetResliceCursor(riw[0]->GetResliceCursor());
>
> rep->GetResliceCursorActor()->
>  GetCursorAlgorithm()->SetReslicePlaneNormal(i);
>
> riw[i]->SetInput(reader->GetOutput());
>  riw[i]->SetSliceOrientation(i);
> riw[i]->SetResliceModeToAxisAligned();
>  }
>
> vtkSmartPointer<vtkCellPicker> picker =
>  vtkSmartPointer<vtkCellPicker>::New();
> picker->SetTolerance(0.005);
>
> vtkSmartPointer<vtkProperty> ipwProp =
> vtkSmartPointer<vtkProperty>::New();
>
> vtkSmartPointer< vtkRenderer > ren =
> vtkSmartPointer< vtkRenderer >::New();
>
> this->ui->view4->GetRenderWindow()->AddRenderer(ren);
> vtkRenderWindowInteractor *iren = this->ui->view4->GetInteractor();
>  //commenting out the following code succesfully applies the
> //'style' to view4
>  //iren->SetInteractorStyle(style);
> //style->SetCurrentRenderer(ren);
>
> for (int i = 0; i < 3; i++)
> {
>  planeWidget[i] = vtkSmartPointer<vtkImagePlaneWidget>::New();
> planeWidget[i]->SetInteractor( iren );
>  planeWidget[i]->SetPicker(picker);
> planeWidget[i]->RestrictPlaneToVolumeOn();
>  double color[3] = {0, 0, 0};
> color[i] = 1;
>  planeWidget[i]->GetPlaneProperty()->SetColor(color);
>
> color[i] = 0.25;
>  riw[i]->GetRenderer()->SetBackground( color );
>
> planeWidget[i]->SetTexturePlaneProperty(ipwProp);
>  planeWidget[i]->TextureInterpolateOff();
> planeWidget[i]->SetResliceInterpolateToCubic();
>  planeWidget[i]->SetInput(reader->GetOutput());
> planeWidget[i]->SetPlaneOrientation(i);
>  planeWidget[i]->SetSliceIndex(imageDims[i]/2);
> planeWidget[i]->DisplayTextOn();
>  planeWidget[i]->SetDefaultRenderer(ren);
> planeWidget[i]->On();
>  planeWidget[i]->InteractionOn();
> planeWidget[i]->SetTextureVisibility(0);
>  }
>
> vtkSmartPointer<vtkResliceCursorCallback> cbk =
>  vtkSmartPointer<vtkResliceCursorCallback>::New();
>
> for (int i = 0; i < 3; i++)
>  {
> cbk->IPW[i] = planeWidget[i];
>  cbk->RCW[i] = riw[i]->GetResliceCursorWidget();
> riw[i]->GetResliceCursorWidget()->AddObserver(
>  vtkResliceCursorWidget::ResliceAxesChangedEvent, cbk );
>
> riw[i]->GetResliceCursorWidget()->AddObserver(
>  vtkResliceCursorWidget::WindowLevelEvent, cbk );
>
> riw[i]->GetResliceCursorWidget()->AddObserver(
>  vtkResliceCursorWidget::ResliceThicknessChangedEvent, cbk );
>
> riw[i]->GetResliceCursorWidget()->AddObserver(
>  vtkResliceCursorWidget::ResetCursorEvent, cbk );
>
> riw[i]->GetInteractorStyle()->AddObserver(
>  vtkCommand::WindowLevelEvent, cbk );
>
> riw[i]->AddObserver(vtkResliceImageViewer::SliceChangedEvent,cbk);
>
> // Make them all share the same color map.
> riw[i]->SetLookupTable(riw[0]->GetLookupTable());
>  planeWidget[i]->GetColorMap()->SetLookupTable(riw[0]->GetLookupTable());
>
> planeWidget[i]->SetColorMap(riw[i]->GetResliceCursorWidget()->GetResliceCursorRepresentation()->GetColorMap());
>
> }
>
>
> //riw[0]->GetRenderWindow()->GetInteractor()->AddObserver(vtkCommand::KeyPressEvent,cbk);
>
> resliceMode(1);
> this->ui->resliceModeCheckBox->setChecked(true);
>
> this->ui->view1->show();
> this->ui->view2->show();
>  this->ui->view3->show();
>
> // Set up action signals and slots
>  this->ui->thickModeCheckBox->setEnabled(0);
> this->ui->resliceModeCheckBox->setEnabled(0);
>
> this->ui->blendModeGroupBox->setEnabled(0);
> this->ui->resetButton->setEnabled(0);
>  this->ui->AddDistance1Button->setEnabled(0);
> };
>
> void QtVTKRenderWindows::resliceMode(int mode)
> {
> for (int i = 0; i < 3; i++)
>  {
> riw[i]->SetResliceMode(mode ? 1 : 0);
>  riw[i]->GetRenderer()->ResetCamera();
> riw[i]->Render();
>  }
> }
>
> void QtVTKRenderWindows::Render()
> {
> for (int i = 0; i < 3; i++)
> {
>  riw[i]->Render();
> }
> this->ui->view3->GetRenderWindow()->Render();
> }
>
> =======================
> QtVTKRenderWindowsApp.cxx
> =======================
>
> #include <QApplication>
> #include "QtVTKRenderWindows.h"
>
> int main( int argc, char** argv )
> {
>   // QT Stuff
>   QApplication app( argc, argv );
>
>   QtVTKRenderWindows myQtVTKRenderWindows(argc, argv);
>   myQtVTKRenderWindows.show();
>
>   return app.exec();
> }
>
>
>
> On Tue, Sep 10, 2013 at 8:14 PM, Alex Malyushytskyy <alexmalvtk at gmail.com>wrote:
>
>> It might be time to attach compilable code.
>>
>> Alex
>>
>>
>> On Mon, Sep 9, 2013 at 4:53 PM, Panayiotis Georgiou <
>> ps.georgiou at gmail.com> wrote:
>>
>>> Thanks for your reply Alex.
>>>
>>> I have tried what you have suggested but it sill doesn't work. I believe
>>> the problem is on how I apply the new style on the three views. As I have
>>> noted in my original post, when I apply the customised style on the 4th
>>> view it works. The way I did that for the 4th view is:
>>>
>>> vtkSmartPointer< vtkRenderer > ren = vtkSmartPointer< vtkRenderer
>>> >::New();
>>>
>>>  this->ui->view4->GetRenderWindow()->AddRenderer(ren);
>>> vtkRenderWindowInteractor *iren = this->ui->view4->GetInteractor();
>>>  iren->SetInteractorStyle(style);
>>> style->SetCurrentRenderer(ren);
>>>
>>> Any other suggestions?
>>>
>>> Thanks.
>>>
>>>
>>> On Mon, Sep 9, 2013 at 9:25 PM, Alex Malyushytskyy <alexmalvtk at gmail.com
>>> > wrote:
>>>
>>>> Override  vtkInteractorStyle::OnChar ( )
>>>>
>>>> Make it do nothing.
>>>>
>>>> Alex
>>>>
>>>>
>>>>
>>>> On Mon, Sep 9, 2013 at 9:37 AM, Panayiotis Georgiou <
>>>> ps.georgiou at gmail.com> wrote:
>>>>
>>>>> Dear vtk users,
>>>>>
>>>>> I am trying to customize the FourPaneViewer example from the provided
>>>>> VTK examples. The full code of the example can be found in
>>>>> VTK_DIR/Examples/GUI/Qt/FourPaneViewer.
>>>>>
>>>>> The example embeds in Qt 4 QVTKWidget views and performs reslicing.
>>>>> One of the views renders (3) vtkImagePlaneWidgets and each of the other 3
>>>>> views renders a vtkResliceImageViewer.
>>>>>
>>>>> What I am trying to achieve is disable in the 3 vtkResliceImageViewers
>>>>> any events triggered by pressing keys on the keyboard, i.e. I want to
>>>>> restrict the user and allow him to interact with these widgets using only
>>>>> the mouse.
>>>>>
>>>>> The way I have tried to do this is by subclassing the
>>>>> vtkInteractorStyle class as follows:
>>>>>
>>>>>     // Define interaction style
>>>>>     class KeyPressInteractorStyle : public vtkInteractorStyle
>>>>>     {
>>>>>     public:
>>>>>     static KeyPressInteractorStyle* New();
>>>>>     vtkTypeMacro(KeyPressInteractorStyle, vtkInteractorStyle);
>>>>>
>>>>>     virtual void OnKeyPress()
>>>>>     {
>>>>>     // Get the keypress
>>>>>     vtkRenderWindowInteractor *rwi = this->Interactor;
>>>>>     std::string key = rwi->GetKeySym();
>>>>>
>>>>>     // Output the key that was pressed
>>>>>     std::cout << "Pressed " << key << std::endl;
>>>>>     qDebug()<< "Pressed " << rwi->GetKeySym();
>>>>>
>>>>>     // Forward events
>>>>>     vtkInteractorStyle::OnKeyPress();
>>>>>     }
>>>>>
>>>>>     };
>>>>>     vtkStandardNewMacro(KeyPressInteractorStyle);
>>>>>
>>>>> and then for each of the 3 views, the customised interaction style is
>>>>> applied as follows:
>>>>>
>>>>>         vtkSmartPointer<KeyPressInteractorStyle> style =
>>>>>     vtkSmartPointer<KeyPressInteractorStyle>::New();
>>>>>
>>>>>
>>>>> this->ui->view1->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style);
>>>>>         style->SetCurrentRenderer(riw[0]->GetRenderer());
>>>>>
>>>>>         this->ui->view1->SetRenderWindow(riw[0]->GetRenderWindow());
>>>>>
>>>>> riw[0]->SetupInteractor(this->ui->view1->GetRenderWindow()->GetInteractor());
>>>>>
>>>>> where view1 is of type QVTKWidget  and riw[i] of type
>>>>> vtkResliceImageViewer.
>>>>>
>>>>> Unfortunately the approach I am using has no effect. The keyboard
>>>>> events are not captured at all by the interaction style. Nothing is printed
>>>>> in the console. It should be noted that if I apply the customised style on
>>>>> the 4th view for vtkImagePlaneWidgets, then it works.
>>>>>
>>>>> Can someone help me to fix this? I am new to VTK and any help will be
>>>>> much appreciated.
>>>>>
>>>>> Thanks for your help,
>>>>>
>>>>> _______________________________________________
>>>>> Powered by www.kitware.com
>>>>>
>>>>> Visit other Kitware open-source projects at
>>>>> http://www.kitware.com/opensource/opensource.html
>>>>>
>>>>> Please keep messages on-topic and check the VTK FAQ at:
>>>>> http://www.vtk.org/Wiki/VTK_FAQ
>>>>>
>>>>> Follow this link to subscribe/unsubscribe:
>>>>> http://www.vtk.org/mailman/listinfo/vtkusers
>>>>>
>>>>>
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20130911/81a7317c/attachment.htm>


More information about the vtkusers mailing list