c++ - VTK 工具包 - vtkCutter 性能

标签 c++ graphics vtk

我使用 VTK Toolkit 加载 OBJ 文件,并使用 vtkCutter 通过播放来剪切数据集,然后绘制剪切的轮廓。对于大型对象,这可能会变得相当慢,正如另一位用户在 VTK Users Forum 中指出的那样。

有没有办法让刀具使用分层数据结构来获得更好的性能?

这是代码:

#include <vtkSmartPointer.h>
#include <vtkCubeSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkPlane.h>
#include <vtkCutter.h>
#include <vtkProperty.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkOBJReader.h>

int main(int argc, char *argv[])
{
    // Parse command line arguments
    if (argc != 2) {
        std::cout << "Usage: " << argv[0] << " Filename(.obj)" << std::endl;
        return EXIT_FAILURE;
    }

    std::string filename = argv[1];
    vtkSmartPointer<vtkOBJReader> obj = vtkSmartPointer<vtkOBJReader>::New();
    obj->SetFileName(filename.c_str());
    obj->Update();

    vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputConnection(obj->GetOutputPort());

    // Create a plane to cut,here it cuts in the XZ direction (xz normal=(1,0,0);XY =(0,0,1),YZ =(0,1,0)
    vtkSmartPointer<vtkPlane> plane = vtkSmartPointer<vtkPlane>::New();
    plane->SetOrigin(0, 0, 0);
    plane->SetNormal(1, 0, 0);

    // Create cutter
    vtkSmartPointer<vtkCutter> cutter = vtkSmartPointer<vtkCutter>::New();
    cutter->SetCutFunction(plane);
    cutter->SetInputConnection(obj->GetOutputPort());
    cutter->Update();

    vtkSmartPointer<vtkPolyDataMapper> cutterMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    cutterMapper->SetInputConnection(cutter->GetOutputPort());

    // Create plane actor
    vtkSmartPointer<vtkActor> planeActor = vtkSmartPointer<vtkActor>::New();
    planeActor->GetProperty()->SetColor(1.0, 1, 0);
    planeActor->GetProperty()->SetLineWidth(2);
    planeActor->SetMapper(cutterMapper);

    // Create cube actor
    vtkSmartPointer<vtkActor> cubeActor = vtkSmartPointer<vtkActor>::New();
    cubeActor->GetProperty()->SetColor(0.5, 1, 0.5);
    cubeActor->GetProperty()->SetOpacity(0.5);
    cubeActor->SetMapper(mapper);

    // Create renderers and add actors of plane and cube
    vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
    renderer->AddActor(planeActor); //display the rectangle resulting from the cut
    renderer->AddActor(cubeActor); //display the cube

    // Add renderer to renderwindow and render
    vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer(renderer);
    renderWindow->SetSize(600, 600);

    vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<
            vtkRenderWindowInteractor>::New();
    interactor->SetRenderWindow(renderWindow);
    renderer->SetBackground(0, 0, 0);
    renderWindow->Render();

    interactor->Start();

    return EXIT_SUCCESS;
}

最佳答案

vtkCutter 使用任意复杂的 func(x,y,z) 对网格进行切片,并在此处使用一个简单的平面来描述该函数,这是一个常见且良好覆盖的特殊情况,因为切割线位于一个简单的平面上,因此将是一个简单的(平坦的)多边形。

  • 这些通用实现通常会消耗大量 CPU 时间,因为所有多边形切割的特殊情况都预计会在 vtkCutter 的情况下发生。
  • 在 VTK 的庞大类层次结构中调用虚拟函数也会导致速度减慢。如果没有特殊的技巧,它完全依赖于编译器来优化循环外的虚拟函数指针查找,而 VTK 在一个或多个嵌套循环中多次调用虚拟函数(例如过滤函数)。 相关信息请参阅:about the cost of virtual function
  • VTK 几乎在任何地方都使用 double,即使可以使用 float。转换和高精度也会增加一些计算和内存开销。
  • VTK (5.8) 并未明确涉及 SSE 等 SIMD 操作,据我所知。
  • ...

搜索如下主题:

尽管在 CPU 上执行此操作,但也可以在变换反馈 channel 中使用 OpenGL 几何着色器来提取由切割平面确定的切割轮廓。在 OpenCL 中执行此操作也是可能的,但是,如果没有可用的基于 GPU 的计算设备,它可能会比 C 或 C++ 实现慢。

要渲染网格,可以使用任何支持 OpenGL 3+ 的渲染器:

更多:What is the best way to have realtime 3D rendering in an engineering application?

关于c++ - VTK 工具包 - vtkCutter 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20081984/

相关文章:

c++ - 为什么 C++ 中没有运算符 ~=?

c++ - 比较顺序无关紧要的两个容器

c# - 使用带抗锯齿的 C# 更改抗锯齿图像的背景颜色

java - 在 Board (JPanel) 中模拟鼠标点击

python - 两个 3d 点之间的 Mayavi 弯曲箭头

c++ - C++14 中 noexcept 说明符的奇怪行为

c++ - 从模板中使用的结构类型中查找类型(可能是底层的)

java - 如何在没有吸引力的情况下将文本与 Graphics2D 对齐?

c++ - vtkSelectVisiblePoints 过滤器输出有 0 个点

javascript - 我如何在需要加载器中用同一张幻灯片更新两个切片