VTK用鼠标画线+VTK坐标转换问题+实例
2018-03-02 17:00
1591 查看
本人在用VTK实现在渲染窗口上用鼠标画线的探究过程。
要在窗口上用鼠标画线首先要做的就是重写鼠标交互事件,于是就在官方网站找到重写鼠标响应事件的demo,然后再更改官方的demo,实现自己需要的功能。我的想法是:
1.获取鼠标左键按下时的坐标。
2.获取鼠标左键上弹时的坐标。
3.用这两个点连接一条线。
遇到的问题时,智能获取到相对于窗口的坐标点,而不是世界相对世界坐标的坐标点。导致的结果就是画线的位置并不是鼠标左键按下和上弹的连线。
在VS下实现的代码如下(没有用cmake管理,直接在vs下做的):
包含一些我在实现的过程中调试的过程,已经注释:#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkSmartPointer.h>
#include <vtkPointPicker.h>
#include <vtkCamera.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkNamedColors.h>
#include <vtkObjectFactory.h>
#include<vtkLine.h>
#include<vtkProperty.h>
#include<vtkPolyLine.h>
#include<vtkUnstructuredGrid.h>
#include<vtkDataSetMapper.h>
#include<vtkLineSource.h>
#include<vtkRendererCollection.h>
#include<vtkCellPicker.h>
#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2); // VTK was built with vtkRenderingOpenGL2
VTK_MODULE_INIT(vtkInteractionStyle);
// Define interaction style
vtkSmartPointer<vtkRenderer> renderer;
double point1[3]{ 0 };
double point2[3]{ 0 };
double WorldPoint[3]{ 0 };
double WorldPoint1[3]{ 0 };
int *clickPos;
int *clickPos1;
class customMouseInteractorStyle : public vtkInteractorStyleTrackballCamera
{
public:
static customMouseInteractorStyle* New();
vtkTypeMacro(customMouseInteractorStyle, vtkInteractorStyleTrackballCamera);
virtual void OnLeftButtonDown()
{
std::cout << "Pressed left mouse button." << std::endl;
// Forward events
// vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
// int* clickPos = this->GetInteractor()->GetEventPosition();
clickPos = this->GetInteractor()->GetEventPosition();
point1[0] = clickPos[0];
point1[1] = clickPos[1];
renderer->SetDisplayPoint(point1[0], point1[1], 0);
renderer->DisplayToWorld();
WorldPoint[0] = (renderer->GetWorldPoint())[0];
WorldPoint[1] = (renderer->GetWorldPoint())[1];
WorldPoint[2] = (renderer->GetWorldPoint())[2];
// double* worldPosition = picker->GetPickPosition();
// std::cout << worldPosition[0] << "\t" << worldPosition[1] << std::endl;
// std::cout << WorldPoint[0]<< std::endl << WorldPoint[1]<< std::endl;
}
virtual void OnLeftButtonUp()
{
std::cout << "Pressed left mouse up." << std::endl;
vtkIdType pts[2]{ 0,1 };
// Forward events
// vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
// int* clickPos = this->GetInteractor()->GetEventPosition();
clickPos1 = this->GetInteractor()->GetEventPosition();
point2[0] = clickPos1[0];
point2[1] = clickPos1[1];
// std::cout << clickPos[0] << std::endl << clickPos[1] << std::endl << std::endl ;
std::cout << point1[0] << std::endl << point1[1] << std::endl;
std::cout << clickPos1[0] << std::endl << clickPos1[1] << std::endl ;
renderer->SetDisplayPoint(point2[0], point2[1], 0);
renderer->DisplayToWorld();
WorldPoint1[0] = (renderer->GetWorldPoint())[0];
WorldPoint1[1] = (renderer->GetWorldPoint())[1];
WorldPoint1[2] = (renderer->GetWorldPoint())[2];
////one way
//renderer->SetDisplayPoint(point1);
//renderer->SetDisplayPoint(point2);
//renderer->DisplayToWorld();
//vtkSmartPointer<vtkPoints>points = vtkSmartPointer<vtkPoints>::New();
//points->InsertNextPoint(point1[0], point1[1], 0);
//points->InsertNextPoint(clickPos1[0], clickPos1[1], 0);
//vtkSmartPointer<vtkPolyLine>polyli
bb41
ne = vtkSmartPointer<vtkPolyLine>::New();
//polyline->GetPointIds()->SetNumberOfIds(2);
//polyline->GetPointIds()->SetId(0, 0);
//polyline->GetPointIds()->SetId(1, 1);
//vtkSmartPointer<vtkUnstructuredGrid>grid= vtkSmartPointer<vtkUnstructuredGrid>::New();
//grid->Allocate(1, 1);
//grid->InsertNextCell(polyline->GetCellType(), polyline->GetPointIds());
//grid->SetPoints(points);
//vtkSmartPointer<vtkDataSetMapper>mapper= vtkSmartPointer<vtkDataSetMapper>::New();
//mapper->SetInputData(grid);
//vtkSmartPointer<vtkActor> actor1 = vtkSmartPointer<vtkActor>::New();
//actor1->SetMapper(mapper);
//actor1->GetProperty()->SetColor(1.0, 0.0, 0.0); //设置颜色
//
//renderer->AddActor(actor1);
//
//renderer->GetRenderWindow()->GetInteractor()->Initialize();
//renderer->GetRenderWindow()->GetInteractor()->Render();
// renderer->GetRenderWindow()->Start();
////the second way
// double* p = renderer->GetActors()->GetLastActor()->GetOrigin();
vtkSmartPointer<vtkLineSource> lineSource = vtkSmartPointer<vtkLineSource>::New();
lineSource->SetPoint1(WorldPoint);
lineSource->SetPoint2(WorldPoint1);
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(lineSource->GetOutputPort());
vtkSmartPointer<vtkActor> actor1 = vtkSmartPointer<vtkActor>::New();
actor1->SetMapper(mapper);
actor1->GetProperty()->SetColor(1.0, 0.0, 0.0);
// actor1->SetOrigin(0, 0,0);
this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(actor1);
renderer->GetRenderWindow()->GetInteractor()->Initialize();
renderer->GetRenderWindow()->GetInteractor()->Render();
// vtkSmartPointer<vtkCellArray>lines = vtkSmartPointer<vtkCellArray>::New();
//// lines->InsertNextCell(2);
// lines->InsertNextCell(2, pts);
// vtkSmartPointer<vtkPolyData>polydata = vtkSmartPointer<vtkPolyData>::New();
// polydata->SetPoints(points);
// polydata->SetPolys(lines);
// vtkSmartPointer<vtkPolyDataMapper>linemapper = vtkSmartPointer<vtkPolyDataMapper>::New();
// linemapper->SetInputData(polydata); //测试划线
// vtkSmartPointer<vtkProperty>linepro = vtkSmartPointer<vtkProperty>::New();
//
// linepro->SetColor(0, 0, 0);
// linepro->SetOpacity(1); //透明度
// vtkSmartPointer<vtkActor>lineact = vtkSmartPointer<vtkActor>::New();
// lineact->SetMapper(linemapper);
// lineact->SetProperty(linepro);
//
// renderer->AddActor(lineact);
// renderer->GetRenderWindow()->Start();
/*vtkSmartPointer<vtkRenderer>render = vtkSmartPointer<vtkRenderer>::New();
render->AddActor(lineact);
vtkSmartPointer<vtkRenderWindow>renwin = vtkSmartPointer<vtkRenderWindow>::New();
renwin->AddRenderer(render);
vtkSmartPointer<vtkRenderWindowInteractor>iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();
iren->SetRenderWindow(renwin);
iren->Initialize();
iren->Start();*/
// renderer->Render();
}
virtual void OnMiddleButtonDown()
{
std::cout << "Pressed middle mouse button." << std::endl;
// Forward events
vtkInteractorStyleTrackballCamera::OnMiddleButtonDown();
}
virtual void OnRightButtonDown()
{
std::cout << "Pressed right mouse button." << std::endl;
// Forward events
vtkInteractorStyleTrackballCamera::OnRightButtonDown();
}
};
vtkStandardNewMacro(customMouseInteractorStyle);
int main(int, char *[])
{
vtkSmartPointer<vtkSphereSource> sphereSource =
vtkSmartPointer<vtkSphereSource>::New();
sphereSource->SetCenter(0.0, 0.0, 0.0);
sphereSource->SetRadius(5.0);
sphereSource->Update();
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(sphereSource->GetOutputPort());
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
vtkSmartPointer<vtkNamedColors> colors =
vtkSmartPointer<vtkNamedColors>::New();
renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->SetBackground(colors->GetColor3d("Slate_grey").GetData());
renderer->AddActor(actor);
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
vtkSmartPointer<customMouseInteractorStyle> style =
vtkSmartPointer<customMouseInteractorStyle>::New();
renderWindowInteractor->SetInteractorStyle(style);
renderWindowInteractor->Initialize();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}结果如下:
关于坐标系的理论就不说了,大家都有买书,书上都有示意图,只是书上可能没有这样的实例。
参考:
VTK官网上鼠标事件自定义:https://lorensen.github.io/VTKExamples/site/Cxx/Interaction/MouseEvents/
坐标转换问题参考了:http://tieba.baidu.com/p/4873446950
这个bug搞了两天,希望可以帮到遇到同样问题的人,节约时间,少走一点弯路。
要在窗口上用鼠标画线首先要做的就是重写鼠标交互事件,于是就在官方网站找到重写鼠标响应事件的demo,然后再更改官方的demo,实现自己需要的功能。我的想法是:
1.获取鼠标左键按下时的坐标。
2.获取鼠标左键上弹时的坐标。
3.用这两个点连接一条线。
遇到的问题时,智能获取到相对于窗口的坐标点,而不是世界相对世界坐标的坐标点。导致的结果就是画线的位置并不是鼠标左键按下和上弹的连线。
在VS下实现的代码如下(没有用cmake管理,直接在vs下做的):
包含一些我在实现的过程中调试的过程,已经注释:#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkSmartPointer.h>
#include <vtkPointPicker.h>
#include <vtkCamera.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkNamedColors.h>
#include <vtkObjectFactory.h>
#include<vtkLine.h>
#include<vtkProperty.h>
#include<vtkPolyLine.h>
#include<vtkUnstructuredGrid.h>
#include<vtkDataSetMapper.h>
#include<vtkLineSource.h>
#include<vtkRendererCollection.h>
#include<vtkCellPicker.h>
#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2); // VTK was built with vtkRenderingOpenGL2
VTK_MODULE_INIT(vtkInteractionStyle);
// Define interaction style
vtkSmartPointer<vtkRenderer> renderer;
double point1[3]{ 0 };
double point2[3]{ 0 };
double WorldPoint[3]{ 0 };
double WorldPoint1[3]{ 0 };
int *clickPos;
int *clickPos1;
class customMouseInteractorStyle : public vtkInteractorStyleTrackballCamera
{
public:
static customMouseInteractorStyle* New();
vtkTypeMacro(customMouseInteractorStyle, vtkInteractorStyleTrackballCamera);
virtual void OnLeftButtonDown()
{
std::cout << "Pressed left mouse button." << std::endl;
// Forward events
// vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
// int* clickPos = this->GetInteractor()->GetEventPosition();
clickPos = this->GetInteractor()->GetEventPosition();
point1[0] = clickPos[0];
point1[1] = clickPos[1];
renderer->SetDisplayPoint(point1[0], point1[1], 0);
renderer->DisplayToWorld();
WorldPoint[0] = (renderer->GetWorldPoint())[0];
WorldPoint[1] = (renderer->GetWorldPoint())[1];
WorldPoint[2] = (renderer->GetWorldPoint())[2];
// double* worldPosition = picker->GetPickPosition();
// std::cout << worldPosition[0] << "\t" << worldPosition[1] << std::endl;
// std::cout << WorldPoint[0]<< std::endl << WorldPoint[1]<< std::endl;
}
virtual void OnLeftButtonUp()
{
std::cout << "Pressed left mouse up." << std::endl;
vtkIdType pts[2]{ 0,1 };
// Forward events
// vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
// int* clickPos = this->GetInteractor()->GetEventPosition();
clickPos1 = this->GetInteractor()->GetEventPosition();
point2[0] = clickPos1[0];
point2[1] = clickPos1[1];
// std::cout << clickPos[0] << std::endl << clickPos[1] << std::endl << std::endl ;
std::cout << point1[0] << std::endl << point1[1] << std::endl;
std::cout << clickPos1[0] << std::endl << clickPos1[1] << std::endl ;
renderer->SetDisplayPoint(point2[0], point2[1], 0);
renderer->DisplayToWorld();
WorldPoint1[0] = (renderer->GetWorldPoint())[0];
WorldPoint1[1] = (renderer->GetWorldPoint())[1];
WorldPoint1[2] = (renderer->GetWorldPoint())[2];
////one way
//renderer->SetDisplayPoint(point1);
//renderer->SetDisplayPoint(point2);
//renderer->DisplayToWorld();
//vtkSmartPointer<vtkPoints>points = vtkSmartPointer<vtkPoints>::New();
//points->InsertNextPoint(point1[0], point1[1], 0);
//points->InsertNextPoint(clickPos1[0], clickPos1[1], 0);
//vtkSmartPointer<vtkPolyLine>polyli
bb41
ne = vtkSmartPointer<vtkPolyLine>::New();
//polyline->GetPointIds()->SetNumberOfIds(2);
//polyline->GetPointIds()->SetId(0, 0);
//polyline->GetPointIds()->SetId(1, 1);
//vtkSmartPointer<vtkUnstructuredGrid>grid= vtkSmartPointer<vtkUnstructuredGrid>::New();
//grid->Allocate(1, 1);
//grid->InsertNextCell(polyline->GetCellType(), polyline->GetPointIds());
//grid->SetPoints(points);
//vtkSmartPointer<vtkDataSetMapper>mapper= vtkSmartPointer<vtkDataSetMapper>::New();
//mapper->SetInputData(grid);
//vtkSmartPointer<vtkActor> actor1 = vtkSmartPointer<vtkActor>::New();
//actor1->SetMapper(mapper);
//actor1->GetProperty()->SetColor(1.0, 0.0, 0.0); //设置颜色
//
//renderer->AddActor(actor1);
//
//renderer->GetRenderWindow()->GetInteractor()->Initialize();
//renderer->GetRenderWindow()->GetInteractor()->Render();
// renderer->GetRenderWindow()->Start();
////the second way
// double* p = renderer->GetActors()->GetLastActor()->GetOrigin();
vtkSmartPointer<vtkLineSource> lineSource = vtkSmartPointer<vtkLineSource>::New();
lineSource->SetPoint1(WorldPoint);
lineSource->SetPoint2(WorldPoint1);
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(lineSource->GetOutputPort());
vtkSmartPointer<vtkActor> actor1 = vtkSmartPointer<vtkActor>::New();
actor1->SetMapper(mapper);
actor1->GetProperty()->SetColor(1.0, 0.0, 0.0);
// actor1->SetOrigin(0, 0,0);
this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(actor1);
renderer->GetRenderWindow()->GetInteractor()->Initialize();
renderer->GetRenderWindow()->GetInteractor()->Render();
// vtkSmartPointer<vtkCellArray>lines = vtkSmartPointer<vtkCellArray>::New();
//// lines->InsertNextCell(2);
// lines->InsertNextCell(2, pts);
// vtkSmartPointer<vtkPolyData>polydata = vtkSmartPointer<vtkPolyData>::New();
// polydata->SetPoints(points);
// polydata->SetPolys(lines);
// vtkSmartPointer<vtkPolyDataMapper>linemapper = vtkSmartPointer<vtkPolyDataMapper>::New();
// linemapper->SetInputData(polydata); //测试划线
// vtkSmartPointer<vtkProperty>linepro = vtkSmartPointer<vtkProperty>::New();
//
// linepro->SetColor(0, 0, 0);
// linepro->SetOpacity(1); //透明度
// vtkSmartPointer<vtkActor>lineact = vtkSmartPointer<vtkActor>::New();
// lineact->SetMapper(linemapper);
// lineact->SetProperty(linepro);
//
// renderer->AddActor(lineact);
// renderer->GetRenderWindow()->Start();
/*vtkSmartPointer<vtkRenderer>render = vtkSmartPointer<vtkRenderer>::New();
render->AddActor(lineact);
vtkSmartPointer<vtkRenderWindow>renwin = vtkSmartPointer<vtkRenderWindow>::New();
renwin->AddRenderer(render);
vtkSmartPointer<vtkRenderWindowInteractor>iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();
iren->SetRenderWindow(renwin);
iren->Initialize();
iren->Start();*/
// renderer->Render();
}
virtual void OnMiddleButtonDown()
{
std::cout << "Pressed middle mouse button." << std::endl;
// Forward events
vtkInteractorStyleTrackballCamera::OnMiddleButtonDown();
}
virtual void OnRightButtonDown()
{
std::cout << "Pressed right mouse button." << std::endl;
// Forward events
vtkInteractorStyleTrackballCamera::OnRightButtonDown();
}
};
vtkStandardNewMacro(customMouseInteractorStyle);
int main(int, char *[])
{
vtkSmartPointer<vtkSphereSource> sphereSource =
vtkSmartPointer<vtkSphereSource>::New();
sphereSource->SetCenter(0.0, 0.0, 0.0);
sphereSource->SetRadius(5.0);
sphereSource->Update();
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(sphereSource->GetOutputPort());
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
vtkSmartPointer<vtkNamedColors> colors =
vtkSmartPointer<vtkNamedColors>::New();
renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->SetBackground(colors->GetColor3d("Slate_grey").GetData());
renderer->AddActor(actor);
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
vtkSmartPointer<customMouseInteractorStyle> style =
vtkSmartPointer<customMouseInteractorStyle>::New();
renderWindowInteractor->SetInteractorStyle(style);
renderWindowInteractor->Initialize();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}结果如下:
关于坐标系的理论就不说了,大家都有买书,书上都有示意图,只是书上可能没有这样的实例。
参考:
VTK官网上鼠标事件自定义:https://lorensen.github.io/VTKExamples/site/Cxx/Interaction/MouseEvents/
坐标转换问题参考了:http://tieba.baidu.com/p/4873446950
这个bug搞了两天,希望可以帮到遇到同样问题的人,节约时间,少走一点弯路。
相关文章推荐
- MFC 菜鸟之问——鼠标移动获取坐标和画线问题
- vtkImageViewer2显示图片开始用鼠标左键交互时,出现的图片突然放大问题
- 设备驱动中的中断问题及实例解析
- vtkBorderWidget设置窗口位置的问题
- 实例解析使用指针作为函数参数传递需要注意的问题
- LINUX USB驱动(4)-鼠标驱动实例
- VTK亲自安装出现的问题及解决办法(WIN7 64位 + VS2012 + VTK-5.10.1)
- 实例详解机器学习如何解决问题
- 最大子数组问题-c++代码实现及运行实例结果
- 【转】使用远程桌面鼠标移动缓慢问题的解决方法
- 美团技术团队:实例详解机器学习如何解决问题(转载)
- 碎片实例:简易版本的新闻应用(碎片+列表显示的问题)
- ogre1.7.2 鼠标独占问题(鼠标移出窗口)
- Excle中出现鼠标无法使用问题
- Unity UGUI 鼠标穿透UI问题
- asp.net经典问题之“未将对象引用设置到对象的实例”
- EM连不上数据库实例的问题
- 几个可运行的,可以说明问题的Ajax实例
- 电脑插入USB鼠标unknown device问题解决方案
- Linux下使用Qtopia时鼠标和串口冲突问题