Environment: VTK8.2.0 + Qt 5.12.2.

I have tried vtkImageActor, vtkActor2D and vtkButtonWidget to make 2D button in different scenes. After comparing them, I think vtkActor2D is the most convenient and the safest solution.

Here is an example using vtkButtonWidget, Use vtkButtonWidget To Create 2D Button.

vtkImageActor is a 3D actor, we need to fix the issue about how to make the button above 3D model and make the button position fixed.

vtkButtonWidget is convient but there is a potential bug about position update when we change the size of vtkRendererWindow. I found that we need to use mouse to do right button click to make sure update position of button correctly. Other event can also work such as rotating and zooming in/out.

Here are some code about vtkActor2D button. The header file point.hpp can be found at the post Project Point On Line And Plane By Special Direction.

#define POINTER_CHECK_WITHBOOL( pointer ) \
      if( nullptr == pointer ) { \
        LOG( ERR, "nullptr, jump out" ); \
        return false; \
    }

#define vSP vtkSmartPointer    
#define vSPNew(Var, Type)    vSP<Type> Var = vSP<Type>::New(); 

#include "point.hpp"

vSP<vtkActor2D> m_SaveButton = vSP<vtkActor2D>::New();


m_Renderer->AddActor2D( m_SaveButton );
m_Renderer->RemoveActor2D( m_SaveButton );

void Update2DActorPos()
{
    m_RenderWindow->Render(); // to get right info for image

    vSPNew(coordinate, vtkCoordinate);
    coordinate->SetCoordinateSystemToNormalizedDisplay();
    coordinate->SetValue(0.5, 0.2);
    int *displayPos = coordinate->GetComputedDisplayValue(m_Renderer);
    Point sizeStruct = GetImageButtonSize( m_SaveButton );
    m_SaveButton->SetDisplayPosition( displayPos[0] - sizeStruct[0]/2, displayPos[1] - sizeStruct[1]/2 );
}

void Init2DButton()
{
    int newSize[3] = { 0 };
    vtkImageData* imgData = pngReader->GetOutput();
    imgData->GetDimensions(newSize);
    newSize[0] *= DevicePixelRatio;
    newSize[1] *= DevicePixelRatio;
    vSPNew(interpolator, vtkImageSincInterpolator);
    vSPNew(resize, vtkImageResize);
    resize->SetInputData(pngReader->GetOutput());
    resize->SetInterpolator(interpolator);
    resize->SetOutputDimensions(newSize[0], newSize[1], 1);
    resize->InterpolateOn();
    resize->Update();

    vSPNew( mapper, vtkImageMapper );
    mapper->SetInputData( resize->GetOutput() );
    mapper->Update();
    mapper->GetInputAlgorithm()->UpdateInformation();
    mapper->SetColorWindow( 256 );
    mapper->SetColorLevel( 128 );
    m_SaveButton->SetMapper( mapper );		
}

Point GetImageButtonSize(vtkActor2D *actor)
{
    vtkMapper2D *mapper = actor->GetMapper();
    // we have to add actor and render before it
    if( nullptr == mapper || nullptr == mapper->GetInputInformation() ||
        nullptr == mapper->GetInputInformation()->Get( vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT() ) )
    {
        return Point( -1, -1, -1 );
    }
    int *ext = mapper->GetInputInformation()->Get( vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT() );
    Point size = Point( ext[1] - ext[0] + 1, ext[3] - ext[2] + 1, 0 );
    return size;
}

bool Is2DImageClicked(vtkActor2D *actor, int x, int y)
{
    POINTER_CHECK_WITHBOOL( actor );
    if( !actor->GetVisibility() )
    {
        return false;
    }
    vtkCoordinate *coordinate = actor->GetPositionCoordinate();
    Point leftBottomPos( coordinate->GetValue() );
    Point rightTopPos;
    vtkMapper2D *mapper = actor->GetMapper();
    POINTER_CHECK_WITHBOOL( mapper );
    POINTER_CHECK_WITHBOOL( mapper->GetInputInformation() );
    int *ext = mapper->GetInputInformation()->Get( vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT() );
    POINTER_CHECK_WITHBOOL( ext );
    Point size = Point( ext[1] - ext[0], ext[3] - ext[2], 0 );
    rightTopPos[0] = leftBottomPos[0] + size[0];
    rightTopPos[1] = leftBottomPos[1] + size[1];
    if ( x > leftBottomPos[0] && x < rightTopPos[0] &&
         y > leftBottomPos[1] && y < rightTopPos[1] )
    {
        return true;
    }
    return false;
}
Categories: VTK

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments

Content Summary
: Input your strings, the tool can get a brief summary of the content for you.

X
0
Would love your thoughts, please comment.x
()
x