VTK工具包-vtkCutter性能

VTK Toolkit - vtkCutter Performance

本文关键字:性能 -vtkCutter 工具包 VTK      更新时间:2023-10-16

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

有没有一种方法可以让刀具使用分层数据结构来获得更好的性能?

这是代码:

#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在一个或多个嵌套循环中多次调用虚拟函数(例如过滤函数)。相关信息请参见此:关于虚拟功能的成本
  • VTK几乎在任何地方都使用doubles,即使可以使用floats。转换和高精度也会增加一些安静的计算和内存开销
  • VTK(5.8)没有明确涉及像SSE、afaik这样的SIMD操作

搜索以下主题:

  • 网格切片算法或软件
  • 从三维网格生成二维截面多边形

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

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

  • Ogre3D
  • Unity3D
  • Irrlicht
  • OSG
  • 一个简单的、自制的OpenGL 3渲染器

更多:在工程应用程序中进行实时3D渲染的最佳方式是什么?