We will got the following left part’s effect when zoom in and zoom out in VTK render window.

How to keep the same display size for the 3D model cube when zoom in or zoom out?

VTK changes camera’s status in the interfaces vtkInteractorStyleTrackballCamera::OnMouseWheelForward and vtkInteractorStyleTrackballCamera::OnMouseWheelBackward, the action Dolly moves camera along view plane’s normal.

this->GrabFocus(this->EventCallbackCommand);
this->StartDolly();
double factor = this->MotionFactor * -0.2 * this->MouseWheelMotionFactor;
this->Dolly(pow(1.1, factor));
this->EndDolly();
this->ReleaseFocus();

So we can scale the model with same factor to make it looks like same display size all the time.

All implementation details are here.

CMakeLists.txt:

project(sameDisplaySize)

find_package( VTK REQUIRED )
include( ${VTK_USE_FILE} )

add_executable(${PROJECT_NAME} "main.cpp" "customIteractorStyle.h" "customIteractorStyle.cpp" )

target_link_libraries( ${PROJECT_NAME} ${VTK_LIBRARIES} )

customIteractorStyle.h:

#pragma once

#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkTransform.h>

#define CPP_SET_MACRO(name,type) \
  void Set##name(type _arg) \
  { \
    if (this->name != _arg) \
    { \
    this->name = _arg; \
    } \
  }

#define vtkSPtr vtkSmartPointer
#define vtkSPtrNew(Var, Type) vtkSPtr<Type> Var = vtkSPtr<Type>::New();

class customIteractorStyle: public vtkInteractorStyleTrackballCamera
{
public:
    static customIteractorStyle *New(){ return new customIteractorStyle(); }
    void OnMouseWheelForward() override;
    void OnMouseWheelBackward() override;
    CPP_SET_MACRO( m_CubeActor, vtkActor *)
protected:    
    customIteractorStyle();
    ~customIteractorStyle() override;
    void ScaleCube( double factor );

    double m_ScaleFator[2];
    vtkActor *m_CubeActor;
};

customIteractorStyle.cpp:

#include "customIteractorStyle.h"

void customIteractorStyle::OnMouseWheelForward()
{
    ScaleCube( m_ScaleFator[0] );
    vtkInteractorStyleTrackballCamera::OnMouseWheelForward();
}

void customIteractorStyle::OnMouseWheelBackward()
{
    ScaleCube( m_ScaleFator[1] );
    vtkInteractorStyleTrackballCamera::OnMouseWheelBackward();
}

customIteractorStyle::customIteractorStyle()
{
    m_CubeActor = nullptr;

    double wheelFactor = 0;
    wheelFactor = this->MotionFactor * (-0.2) * this->MouseWheelMotionFactor;
    m_ScaleFator[0] = pow(1.1, wheelFactor); // forward wheel
    wheelFactor = this->MotionFactor * 0.2 * this->MouseWheelMotionFactor;
    m_ScaleFator[1] = pow(1.1, wheelFactor); // back wheel
}

customIteractorStyle::~customIteractorStyle()
{
    m_CubeActor = nullptr;
}

void customIteractorStyle::ScaleCube(double factor)
{
    vtkSPtrNew( scaleTrans, vtkTransform );
    scaleTrans->Scale( factor, factor, factor );
    scaleTrans->Update();

    vtkSPtrNew( trans, vtkTransform );
    trans->Concatenate( m_CubeActor->GetUserTransform() );
    trans->Concatenate( scaleTrans );
    trans->Update();

    m_CubeActor->SetUserTransform( trans );
}

main.cpp:

#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkCubeSource.h>
#include <vtkAxesActor.h>
#include <vtkTransform.h>
#include "customIteractorStyle.h"

using namespace std;

int main()
{
    vtkSPtrNew( cube, vtkCubeSource );
    cube->Update();
    vtkSPtrNew( mapper, vtkPolyDataMapper );
    mapper->SetInputData( cube->GetOutput() );
    vtkSPtrNew( cubeActor, vtkActor );
    cubeActor->SetMapper( mapper );
    vtkSPtrNew( userTrans, vtkTransform );
    userTrans->Translate( 0, 1, 0 );
    userTrans->RotateZ( 45 );
    userTrans->Update();
    cubeActor->SetUserTransform( userTrans );

    vtkSPtrNew( axesActor, vtkAxesActor );

    vtkSPtrNew( renderer, vtkRenderer );
    renderer->AddActor( axesActor );
    renderer->AddActor( cubeActor );
    renderer->SetBackground( 0, 0, 0 );

    vtkSPtrNew( renderWindow, vtkRenderWindow );
    renderWindow->AddRenderer( renderer );

    vtkSPtrNew( renderWindowInteractor, vtkRenderWindowInteractor );
    renderWindowInteractor->SetRenderWindow( renderWindow );

    vtkSPtrNew( style, customIteractorStyle );
    style->Setm_CubeActor( cubeActor );
    renderWindowInteractor->SetInteractorStyle( style );

    renderer->ResetCamera();
    renderWindow->Render();
    renderWindowInteractor->Start();
    return 0;
}

Output:

Categories: VTK

0 0 vote
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
A prohibited operation
0
Would love your thoughts, please comment.x
()
x