环境 Qt6.7+vtk9.3+vs2022
效果:
vtk鼠标位置缩放
如视频所示,鼠标不管在哪个位置鼠标滚轮都能按照鼠标位置缩放
注意::以下代码为以前编写的 可能有问题,
往后找2024/10/16的代码,一共4个文件 直接拉出来用
步骤
咋们要实现这个功能,继承vtkInteractorStyleTrackballCamera类
然后重写Dolly()
或者重写OnMouseWheelForward()与OnMouseWheelBackward()
其他不多说 直接代码
class CustomInteractorStyle:public vtkInteractorStyleTrackballCamera{
public:
static CustomInteractorStyle* New(){
CustomInteractorStyle* self = new CustomInteractorStyle();
}
vtkTypeMacro(CustomInteractorStyle,vtkInteractorStyleTrackballCamera);
//方案一:重写滚轮事件,好处在于可以自定义一个bool变量是否按照鼠标位置进行缩放
virtual void OnMouseWheelForward()override{
if(Zoomflag){
Dolly(1.1);
}else{
vtkInteractorStyleTrackballCamera::OnMouseWheelForward();
}
}
virtual void OnMouseWheelBackward()override{
if(Zoomflag){
Dolly(0.9);
}else{
vtkInteractorStyleTrackballCamera::OnMouseWheelBackward();
}
}
//方案二:注意如果选择重写滚轮事件这句话注释掉
//using vtkInteractorStyleTrackballCamera::Dolly;
protected:
//方案二:注意如果选择重写滚轮事件这句话注释掉
//void Dolly(double factor)override{
void Dolly(double factor)
{
DollyToPofsition(factor, this->Interactor->GetEventPosition(), this->GetDefaultRenderer());
//这一句必须加,不然图像不出现,得拖拽一下
this->GetDefaultRenderer()->ResetCameraClippingRange();
m_rendererwindow->Render();
}
void DollyToPosition(double fact, int* position, vtkRenderer* renderer)
{
vtkCamera* cam = renderer->GetActiveCamera();
if (cam->GetParallelProjection())
{
int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
// 相对于光标缩放
int* aSize = renderer->GetRenderWindow()->GetSize();
int w = aSize[0];
int h = aSize[1];
x0 = w / 2;
y0 = h / 2;
x1 = position[0];
y1 = position[1];
vtkPVInteractorStyle::TranslateCamera(renderer, x0, y0, x1, y1);
cam->SetParallelScale(cam->GetParallelScale() / fact);
vtkPVInteractorStyle::TranslateCamera(renderer, x1, y1, x0, y0);
}
else
{
// 相对于光标位置进行缩放
double viewFocus[4], originalViewFocus[3], cameraPos[3], newCameraPos[3];
double newFocalPoint[4], norm[3];
// 将焦点移动到光标位置
cam->GetPosition(cameraPos);
cam->GetFocalPoint(viewFocus);
cam->GetFocalPoint(originalViewFocus);
cam->GetViewPlaneNormal(norm);
CustomInteractorStyle::ComputeWorldToDisplay(
renderer, viewFocus[0], viewFocus[1], viewFocus[2], viewFocus);
CustomInteractorStyle::ComputeDisplayToWorld(
renderer, double(position[0]), double(position[1]), viewFocus[2], newFocalPoint);
cam->SetFocalPoint(newFocalPoint);
// 沿投影方向移入/移出相机
cam->Dolly(fact);
// 寻找新的焦点
cam->GetPosition(newCameraPos);
double newPoint[3];
newPoint[0] = originalViewFocus[0] + newCameraPos[0] - cameraPos[0];
newPoint[1] = originalViewFocus[1] + newCameraPos[1] - cameraPos[1];
newPoint[2] = originalViewFocus[2] + newCameraPos[2] - cameraPos[2];
cam->SetFocalPoint(newPoint);
}
}
void TranslateCamera(vtkRenderer* renderer, int toX, int toY, int fromX, int fromY)
{
vtkCamera* cam = renderer->GetActiveCamera();
double viewFocus[4], focalDepth, viewPoint[3];
double newPickPoint[4], oldPickPoint[4], motionVector[3];
cam->GetFocalPoint(viewFocus);
CustomInteractorStyle::ComputeWorldToDisplay(
renderer, viewFocus[0], viewFocus[1], viewFocus[2], viewFocus);
focalDepth = viewFocus[2];
CustomInteractorStyle::ComputeDisplayToWorld(
renderer, double(toX), double(toY), focalDepth, newPickPoint);
CustomInteractorStyle::ComputeDisplayToWorld(
renderer, double(fromX), double(fromY), focalDepth, oldPickPoint);
//摄像机运动反向
motionVector[0] = oldPickPoint[0] - newPickPoint[0];
motionVector[1] = oldPickPoint[1] - newPickPoint[1];
motionVector[2] = oldPickPoint[2] - newPickPoint[2];
cam->GetFocalPoint(viewFocus);
cam->GetPosition(viewPoint);
cam->SetFocalPoint(motionVector[0] + viewFocus[0], motionVector[1] + viewFocus[1], motionVector[2] + viewFocus[2]);
cam->SetPosition(motionVector[0] + viewPoint[0], motionVector[1] + viewPoint[1], motionVector[2] +viewPoint[2]);
}
private:
bool Zoomflag = false;
//自行加函数获取
vtkGenericOpenGLRenderWindow* m_rendererwindow;
};
最新代码话不多说
鼠标平移缩放旋转
左键平移 右键旋转 可以给中心点旋转,滚轮缩放(可以鼠标位置缩放)
VTKStyle.h
#pragma once
#include <vtkRenderer.h>
#include <vtkSmartPointer.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkCamera.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkInteractorStyleRubberBandZoom.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderedAreaPicker.h>
#include <vtkCoordinate.h>
#include <vtkObjectFactory.h>
#include <vtkVertexGlyphFilter.h>
#include <vtkPoints.h>
#include <vtkPolyLine.h>
#include <vtkCellArray.h>
#include <vtkPolyData.h>
#include <vtkActor2D.h>
#include <vtkPolyDataMapper2D.h>
#include <vtkProperty2D.h>
#include <vtkMapper2D.h>
#include <vtkRendererCollection.h>
#include <vtkUnsignedCharArray.h>
#include <vtkPointPicker.h>
#include <vtkIdTypeArray.h>
#include <vtkGlyph3D.h>
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkMath.h>
#include <vtkTextActor.h>
#include <vtkUnsignedCharArray.h>
#include <vtkPointData.h>
#include <vtkPropPicker.h>
#include <QStringList>
#include <QString>
#include <windows.h>
#include <QTimer>
#include <thread>
#include <vtkSmartPointer.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkPolyData.h>
#include <vtkPoints.h>
#include <vtkCellArray.h>
#include <vtkVertexGlyphFilter.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPolyLine.h>
#include <vtkUnsignedCharArray.h>
#include <QResizeEvent>
#include <vtkOrientationMarkerWidget.h>
#include <vtkAxesActor.h>
#include <vtkOutputWindow.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <QColor>
#include <vtkLine.h>
#include <vtkTransform.h>
#include <vtkSTLReader.h>
#include <vtkMaskPoints.h>
#include <vtkTransformPolyDataFilter.h>
#include <QFileDialog>
#include <QShowEvent>
#include "math.h"
#include <QRandomGenerator>
namespace {
enum PanAxis {
AXIS_X = 0,
AXIS_Y,
AXIS_XY
};
}
//自定义鼠标事件类
class VTKStyle :public vtkInteractorStyleTrackballCamera {
public:
static VTKStyle* New();
vtkTypeMacro(VTKStyle, vtkInteractorStyleTrackballCamera);
public:
void SetCenter(double* center);
void setRenderWindow(vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderwindow);
private:
void TranslatemousePos(int* pos);
void DollToPosition(double fact, int* position, vtkRenderer* renderer);
void TranslateCamera(vtkRenderer* renderer, int toX, int toY, int fromX, int fromY);
void ComputeDisplayCenter();
protected:
//using vtkInteractorStyleTrackballCamera::Dolly;
//void Dolly(double factor)override;
virtual void OnLeftButtonDown()override;
virtual void OnLeftButtonUp()override;
virtual void OnRightButtonDown()override;
virtual void OnRightButtonUp()override;
virtual void OnMouseWheelForward()override;
virtual void OnMouseWheelBackward()override;
virtual void OnMouseMove() override;
private:
vtkSmartPointer<vtkGenericOpenGLRenderWindow>m_renderWindow;
bool m_leftBtn = false;
bool m_rightBtn = false;
double m_mousePos[3] = {
0,0,0 };
double m_Center[3] = {
500,500,500 };
double m_DisplayCenter[2] = {
0,0 };
double m_RotationFactor = 1.0;
bool m_mouseEvent = true;
PanAxis m_AxisOfMovement = AXIS_XY;
};
VTKStyle.cpp
#include "VTKStyle.h"
VTKStyle* VTKStyle::New()
{
VTKStyle* self = new VTKStyle();
self->InitializeObjectBase();
return self;
}
void VTKStyle::SetCenter(double* center) {
m_Center[0] = center[

与鼠标点缩放(鼠标位置缩放)&spm=1001.2101.3001.5002&articleId=136214860&d=1&t=3&u=7e5e7a6e4916412b8e190a4c47e3b23d)
336

被折叠的 条评论
为什么被折叠?



