[vtk-developers] vtkBorderWidget events

Karthik Krishnan karthik.krishnan at kitware.com
Tue Oct 26 11:00:12 EDT 2010


Leonardo:

The BorderWidget is going to work correctly if you change the
co-ordinate system of the PositionCoordinate and the
Position2Coordinate of its representation. It is assumed that those
ivars are always in the NormalizedViewport coordinate system.

There are a lot of excerpts like this in BorderWidget...

void vtkBorderWidget::SelectAction(vtkAbstractWidget *w)
{
....
  // Picked something inside the widget
  int X = self->Interactor->GetEventPosition()[0];
  int Y = self->Interactor->GetEventPosition()[1];

  // convert to normalized viewport coordinates
  double XF = static_cast<double>(X);
  double YF = static_cast<double>(Y);
  self->CurrentRenderer->DisplayToNormalizedDisplay(XF,YF);
  self->CurrentRenderer->NormalizedDisplayToViewport(XF,YF);
  self->CurrentRenderer->ViewportToNormalizedViewport(XF,YF);
  ...
    vtkBorderRepresentation *rep =
reinterpret_cast<vtkBorderRepresentation*>(self->WidgetRep);
    double *fpos1 = rep->GetPositionCoordinate()->GetValue();
    double *fpos2 = rep->GetPosition2Coordinate()->GetValue();

    eventPos[0] = (XF-fpos1[0])/fpos2[0];
    eventPos[1] = (YF-fpos1[1])/fpos2[1];

    self->SelectRegion(eventPos);
    }


The GetValue() on the coordinate is going to return values in that
coordinate system. If its anything other than NormalizedViewport, will
not play well with the other variables in there.



This is (arguably) a bug, but you can work around this by defining
your border widget's position in the NormalizedViewport frame of
reference.

HTH
--
karthik

On Tue, Oct 26, 2010 at 7:55 PM, Leonardo M. Ramé <l.rame at griensu.com> wrote:
> On 2010-10-26 09:14:05 -0400, David Doria wrote:
>> Can you post the shortest compilable code that demonstrates this?
>>
>> David
>
> Here is the code of my app. This is a QT 4.7 app that requires vtk 5.6,
> it's requires only the "dcmwidget.h" header. All of its functionality is
> in mainwindow.cpp
>
> The app shows a QTVTKWidget as the central app widget, containing a
> vtkImageViewer2, where you can select an area with a rubberband, then,
> a vtkBorderWidget is created with the rubberband data.
>
> If you look at the mouseReleaseEvent, an observer is added to the
> vtkBorderWidget to catch its events using the vtkWidgetCallback defined
> in dcmwidget.h, but only the events 33 and 44 are catched.
>
> I hope you can help me.
>
> ---------------------------------------
> -- dcmwidget.h ------------------------
> ---------------------------------------
>
> #ifndef DCMWIDGET_H
> #define DCMWIDGET_H
>
> #include "QMouseEvent"
> #include "vtkImageData.h"
> #include "vtkImageViewer2.h"
> #include "vtkRenderer.h"
> #include "vtkInteractorStyleRubberBand2D.h"
> #include "QVTKWidget.h"
> #include "vtkAbstractWidget.h"
>
> class vtkWidgetCallback : public vtkCommand
> {
> public:
>    static vtkWidgetCallback *New()
>    {
>        return new vtkWidgetCallback;
>    }
>
>    virtual void Execute(vtkObject *caller, unsigned long EventId, void*)
>    {
>      std::cout << "class: " << caller->GetClassName() << " - EventId: " << EventId << std::endl;
>    }
>
>    vtkAbstractWidget * getWidget()
>    {
>        return m_widget;
>    }
>
>    void setWidget(vtkAbstractWidget * AWidget)
>    {
>        m_widget = AWidget;
>    }
>
> private:
>    vtkAbstractWidget* m_widget;
> };
>
> class MyRubberBand : public vtkInteractorStyleRubberBand2D
> {
>  public:
>    static MyRubberBand* New();
>    vtkTypeRevisionMacro(MyRubberBand, vtkInteractorStyleRubberBand2D);
>
>    void GetPosition(double &x0, double &y0, double &x1, double &y1)
>    {
>        double worldPt[3];
>        this->ComputeDisplayToWorld(this->StartPosition[0], this->StartPosition[1], 0, worldPt);
>        x0 = worldPt[0];
>        y0 = worldPt[1];
>        this->ComputeDisplayToWorld(this->EndPosition[0], this->EndPosition[1], 0, worldPt);
>        x1 = worldPt[0];
>        y1 = worldPt[1];
>    };
> };
>
> class DCMWidget : public QVTKWidget
> {
>     Q_OBJECT
> public:
>    DCMWidget();
> private:
>    void mouseReleaseEvent (QMouseEvent* e);
>    MyRubberBand * m_rubberBand;
>    vtkImageData * m_imageDataVTK;
>    vtkImageViewer2 * m_ImageViewer;
>    vtkRenderer * m_renderer;
>    vtkWidgetCallback * m_widgetCallback;
> };
>
> #endif // DCMWIDGET_H
>
> ---------------------------------------
> -- mainwindow.h -----------------------
> ---------------------------------------
>
> #ifndef MAINWINDOW_H
> #define MAINWINDOW_H
>
> #include <QMainWindow>
> #include "QVTKWidget.h"
> h
>
> namespace Ui {
>    class MainWindow;
> }
>
> class MainWindow : public QMainWindow
> {
>    Q_OBJECT
>
> public:
>    explicit MainWindow(QWidget *parent = 0);
>    ~MainWindow();
>
> private:
>    Ui::MainWindow *ui;
>    QVTKWidget * m_vtkWidget;
>
> };
>
>
> #endif // MAINWINDOW_H
>
> ---------------------------------------
> -- mainwindow.cpp ---------------------
> ---------------------------------------
>
> #include "mainwindow.h"
> #include "ui_mainwindow.h"
> #include "vtkObjectFactory.h"
> #include "vtkInteractorStyleImage.h"
> #include "vtkAbstractWidget.h"
> #include "vtkBorderRepresentation.h"
> #include "vtkBorderWidget.h"
> #include "dcmwidget.h"
>
> DCMWidget::DCMWidget()
> {
>    m_imageDataVTK = vtkImageData::New();
>    m_imageDataVTK->SetDimensions(1500, 1500, 1);
>    m_imageDataVTK->SetScalarTypeToUnsignedShort();
>
>    m_ImageViewer = vtkImageViewer2::New();
>    m_renderer = vtkRenderer::New();
>
>    this->SetRenderWindow(m_ImageViewer->GetRenderWindow());
>    m_ImageViewer->SetInput( m_imageDataVTK);
>    m_ImageViewer->SetRenderWindow(this->GetRenderWindow());
>    m_ImageViewer->SetupInteractor(this->GetInteractor());
>    m_ImageViewer->GetRenderer()->ResetCamera();
>    m_ImageViewer->Render();
>
>    m_widgetCallback = vtkWidgetCallback::New();
>
>    m_rubberBand = MyRubberBand::New();
>    this->GetInteractor()->SetInteractorStyle(m_rubberBand);
> }
>
> void DCMWidget::mouseReleaseEvent (QMouseEvent* e)
> {
>    if(m_rubberBand)
>    {
>        double x0;
>        double y0;
>        double x1;
>        double y1;
>
>        m_rubberBand->GetPosition(x0, y0, x1, y1);
>
>        m_rubberBand->Delete();
>        m_rubberBand = NULL;
>
>        this->GetInteractor()->SetInteractorStyle(this->m_ImageViewer->GetInteractorStyle());
>
>        vtkAbstractWidget * lWidget = vtkBorderWidget::New();
>        lWidget->SetInteractor(this->GetInteractor());
>        lWidget->CreateDefaultRepresentation();
>
>        vtkBorderRepresentation * borderRep = vtkBorderRepresentation::SafeDownCast(lWidget->GetRepresentation());
>        borderRep->GetPositionCoordinate()->SetCoordinateSystemToWorld();
>        borderRep->GetPositionCoordinate()->SetValue(x0, y0);
>        borderRep->GetPosition2Coordinate()->SetCoordinateSystemToWorld();
>        borderRep->GetPosition2Coordinate()->SetValue(x1 - x0, y1 - y0);
>        lWidget->AddObserver(vtkCommand::AnyEvent, m_widgetCallback);
>        lWidget->On();
>    }
>
>    e->accept();
>    QVTKWidget::mouseReleaseEvent(e);
>    update();
> }
>
> vtkCxxRevisionMacro(MyRubberBand, "$Revision: 1.1 $");
> vtkStandardNewMacro(MyRubberBand);
>
> MainWindow::MainWindow(QWidget *parent) :
>    QMainWindow(parent),
>    ui(new Ui::MainWindow)
> {
>    ui->setupUi(this);
>
>    m_vtkWidget = new DCMWidget;
>    this->setCentralWidget(m_vtkWidget);
> }
>
> MainWindow::~MainWindow()
> {
>    delete ui;
> }
>
> --
> Leonardo M. Ramé
> http://leonardorame.blogspot.com
> _______________________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>
> Follow this link to subscribe/unsubscribe:
> http://www.vtk.org/mailman/listinfo/vtk-developers
>
>



More information about the vtk-developers mailing list