欢迎访问宙启技术站
智能推送

使用vtkRenderWindowInteractor()实现模型的测量和标注功能

发布时间:2023-12-26 06:53:31

vtkRenderWindowInteractor是VTK(Visualization Toolkit)中的一个交互式窗口处理类,可以用于实现模型的测量和标注功能。下面将演示如何使用vtkRenderWindowInteractor实现这些功能,并附带一个简单的使用例子。

首先,我们需要引入必要的VTK库和头文件:

#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkCoordinate.h>
#include <vtkProperty.h>
#include <vtkPointPicker.h>
#include <vtkCallbackCommand.h>
#include <vtkTextActor.h>
#include <vtkTextProperty.h>

接下来,我们创建一个vtkRenderWindowInteractor对象,并将其设置为vtkRenderWindow的交互器:

vtkSmartPointer<vtkRenderWindowInteractor> interactor =
    vtkSmartPointer<vtkRenderWindowInteractor>::New();

vtkSmartPointer<vtkRenderWindow> renderWindow =
    vtkSmartPointer<vtkRenderWindow>::New();

renderWindow->SetInteractor(interactor);

然后,我们创建一个vtkRenderer对象,并将其添加到vtkRenderWindow中:

vtkSmartPointer<vtkRenderer> renderer =
    vtkSmartPointer<vtkRenderer>::New();

renderWindow->AddRenderer(renderer);

现在,我们可以向vtkRenderer中添加模型数据。例如,我们可以添加一个球体:

vtkSmartPointer<vtkSphereSource> sphereSource =
    vtkSmartPointer<vtkSphereSource>::New();

vtkSmartPointer<vtkPolyDataMapper> sphereMapper =
    vtkSmartPointer<vtkPolyDataMapper>::New();
sphereMapper->SetInputConnection(sphereSource->GetOutputPort());

vtkSmartPointer<vtkActor> sphereActor =
    vtkSmartPointer<vtkActor>::New();
sphereActor->SetMapper(sphereMapper);

renderer->AddActor(sphereActor);

接下来,我们定义一些用于测量和标注的变量和函数。例如,我们可以通过拾取点的方法获取鼠标在模型中的坐标:

vtkSmartPointer<vtkPointPicker> picker =
    vtkSmartPointer<vtkPointPicker>::New();

vtkSmartPointer<vtkCallbackCommand> pickCallback =
    vtkSmartPointer<vtkCallbackCommand>::New();
pickCallback->SetCallback(PickCallback);

interactor->SetPicker(picker);
interactor->AddObserver(vtkCommand::LeftButtonPressEvent, pickCallback);

上面的PickCallback函数是一个回调函数,在用户点击鼠标左键时被调用,可以在函数中获取鼠标的坐标,然后进行测量或标注的操作。

最后,我们设置渲染窗口的一些属性,并启动交互器:

renderWindow->SetSize(800, 600);
interactor->Initialize();
interactor->Start();

完整的使用例子如下所示:

#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkCoordinate.h>
#include <vtkProperty.h>
#include <vtkPointPicker.h>
#include <vtkCallbackCommand.h>
#include <vtkTextActor.h>
#include <vtkTextProperty.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>

vtkRenderWindowInteractor* interactor;
vtkSmartPointer<vtkPointPicker> picker;
vtkSmartPointer<vtkCallbackCommand> pickCallback;
vtkSmartPointer<vtkTextActor> textActor;

void PickCallback(vtkObject* caller, long unsigned int eventId,
                  void* callData)
{
    vtkRenderWindowInteractor* inter = dynamic_cast<vtkRenderWindowInteractor*>(caller);
    vtkPointPicker* pointPicker = dynamic_cast<vtkPointPicker*>(inter->GetPicker());

    if (pointPicker == nullptr)
        return;

    double pickedPoint[3];
    pointPicker->GetPickPosition(pickedPoint);

    vtkCoordinate* coordinate = vtkCoordinate::New();
    coordinate->SetCoordinateSystemToWorld();

    double worldPoint[3];
    coordinate->SetValue(pickedPoint[0], pickedPoint[1], pickedPoint[2]);
    coordinate->GetComputedWorldValue(renderer, worldPoint);

    char coordinatesStr[100];
    sprintf(coordinatesStr, "(%.2f, %.2f, %.2f)", worldPoint[0], worldPoint[1], worldPoint[2]);

    textActor->SetInput(coordinatesStr);
    renderer->AddActor(textActor);
    interactor->Render();

    coordinate->Delete();
}

int main()
{
    vtkSmartPointer<vtkRenderWindowInteractor> interactor =
        vtkSmartPointer<vtkRenderWindowInteractor>::New();

    vtkSmartPointer<vtkRenderWindow> renderWindow =
        vtkSmartPointer<vtkRenderWindow>::New();

    renderWindow->SetInteractor(interactor);

    vtkSmartPointer<vtkRenderer> renderer =
        vtkSmartPointer<vtkRenderer>::New();

    renderWindow->AddRenderer(renderer);

    vtkSmartPointer<vtkSphereSource> sphereSource =
        vtkSmartPointer<vtkSphereSource>::New();

    vtkSmartPointer<vtkPolyDataMapper> sphereMapper =
        vtkSmartPointer<vtkPolyDataMapper>::New();
    sphereMapper->SetInputConnection(sphereSource->GetOutputPort());

    vtkSmartPointer<vtkActor> sphereActor =
        vtkSmartPointer<vtkActor>::New();
    sphereActor->SetMapper(sphereMapper);

    renderer->AddActor(sphereActor);

    vtkSmartPointer<vtkInteractorStyleTrackballCamera> style =
        vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();

    picker = vtkSmartPointer<vtkPointPicker>::New();

    pickCallback = vtkSmartPointer<vtkCallbackCommand>::New();
    pickCallback->SetCallback(PickCallback);

    interactor->SetPicker(picker);
    interactor->SetInteractorStyle(style);
    interactor->AddObserver(vtkCommand::LeftButtonPressEvent, pickCallback);

    textActor = vtkSmartPointer<vtkTextActor>::New();
    textActor->SetPosition(10, 10);
    textActor->SetInput("(0, 0, 0)");

    renderer->AddActor(textActor);

    renderWindow->SetSize(800, 600);
    interactor->Initialize();
    interactor->Start();

    return 0;
}

在这个例子中,我们创建了一个球体模型,并实现了通过鼠标点击球体来获取坐标的功能。当用户点击鼠标左键时,会在渲染窗口中显示当前点的坐标。可以根据需要进行适当的修改,实现其他测量和标注的功能。

这就是使用vtkRenderWindowInteractor实现模型的测量和标注功能的基本步骤和示例。通过使用vtkRenderWindowInteractor,我们可以方便地与模型进行交互,并实现丰富的功能。