VTK实现actor和坐标轴 缩放不变

VTK实现actor和坐标轴 缩放不变

描述

实现滚动鼠标中键(移动相机)时,保持坐标轴或者指定的actor在屏幕上看起来大小不变。
效果如下:视频中,立方体和坐标轴都设置了缩放不变,而旁边的圆柱体正常缩放。

vtk actor 和坐标轴缩放不变(相机距离不影响actor在屏幕上的大小)

源码

//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
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

class customIteractorStyle: public vtkInteractorStyleTrackballCamera
{
public:
    static customIteractorStyle *New(){ return new customIteractorStyle(); }
    void OnMouseWheelForward() override;
    void OnMouseWheelBackward() override;
    void SetFixedRegularActor(vtkActor * actor);
    void SetFixedAxesActor(vtkAxesActor * actor);

protected:    
    customIteractorStyle();
    ~customIteractorStyle() override;
    void ScaleCube( double factor );
    void ScaleAxes( double factor );

    double m_ScaleFator[2];
    vtkActor *m_regularActor;
    vtkAxesActor* m_axesActor;
};

=========================================================================

//customIteractorStyle.cpp
#include "customIteractorStyle.h"

#include 

//VTK_MODULE_INIT(vtkRenderingOpenGL2)
//VTK_MODULE_INIT(vtkRenderingFreeType)
VTK_MODULE_INIT(vtkInteractionStyle)
//VTK_MODULE_INIT(vtkRenderingContextOpenGL2)
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2);

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

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

void customIteractorStyle::SetFixedRegularActor(vtkActor *actor)
{
    if(this->m_regularActor!=actor)
    {
        this->m_regularActor=actor;
    }
}

void customIteractorStyle::SetFixedAxesActor(vtkAxesActor *actor)
{
    if(this->m_axesActor!=actor)
    {
        this->m_axesActor=actor;
    }
}

customIteractorStyle::customIteractorStyle()
{
    m_regularActor = nullptr;
    m_axesActor = 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_regularActor = nullptr;
    m_axesActor = nullptr;
}

void customIteractorStyle::ScaleCube(double factor)
{
    if(m_regularActor==nullptr)
    {
        return;
    }
    vtkNew<vtkTransform> scaleTrans;
    scaleTrans->Scale( factor, factor, factor );
    scaleTrans->Update();

    vtkNew<vtkTransform> transC;
    transC->Concatenate( m_regularActor->GetUserTransform() );
    transC->Concatenate( scaleTrans );
    transC->Update();

    m_regularActor->SetUserTransform( transC );
}

void customIteractorStyle::ScaleAxes(double factor)
{
    if(m_axesActor==nullptr)
    {
        return;
    }
    vtkNew<vtkTransform> scaleTrans;
    scaleTrans->Scale( factor, factor, factor );
    scaleTrans->Update();


    vtkNew<vtkTransform> trans;
    trans->Concatenate( m_axesActor->GetUserTransform() );
    trans->Concatenate( scaleTrans );
    trans->Update();
    m_axesActor->SetUserTransform( trans );
}

=========================================================================

//main.cpp
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "customIteractorStyle.h"

using namespace std;

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

    vtkNew<vtkAxesActor> axesActor;
    vtkNew<vtkTransform>  userTrans2;
    userTrans2->Update();
    axesActor->SetUserTransform( userTrans2 );
    axesActor->AxisLabelsOff();
    axesActor->SetTotalLength(10,1,1);


    vtkNew<vtkCylinderSource> cylinder;
    cylinder->Update();
    vtkNew<vtkPolyDataMapper> cylinderMapper;
    cylinderMapper->SetInputData(cylinder->GetOutput());
    vtkNew<vtkActor> cylinderActor;
    cylinderActor->SetMapper(cylinderMapper);
    cylinderActor->SetPosition(1,1,1);

    vtkNew<vtkRenderer> renderer;
    renderer->AddActor( axesActor );
    renderer->AddActor( cubeActor );
    renderer->AddActor( cylinderActor );
    renderer->SetBackground( 0, 0, 0 );

    vtkNew<vtkRenderWindow> renderWindow;
    renderWindow->AddRenderer( renderer );

    vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
    renderWindowInteractor->SetRenderWindow( renderWindow );

    vtkNew<customIteractorStyle> style;
    style->SetFixedRegularActor( cubeActor );
    style->SetFixedAxesActor(axesActor );
    renderWindowInteractor->SetInteractorStyle( style );

//    renderer->GetActiveCamera()->SetParallelProjection(1);

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

参考链接

有修改,添加了坐标轴缩放不变
https://www.weiy.city/2020/10/keep-model-same-display-size-when-zooming-in-out/

你可能感兴趣的:(VTK,c++,医学图像处理,c++,开发语言)