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 <iostream>
#include <vtkSmartPointer.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkTransform.h>
#include <vtkAxesActor.h>
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 <vtkAutoInit.h>
//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 <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 <vtkCylinderSource.h>
#include <vtkCamera.h>
#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/