C++ VTK工具包-vtkCutter性能

C++ VTK工具包-vtkCutter性能,c++,graphics,vtk,C++,Graphics,Vtk,我使用VTK工具包加载一个OBJ文件和一个vtkCutter,通过播放剪切数据集,然后绘制剪切轮廓。对于大型对象,这可能会变得非常缓慢,正如另一位用户在中指出的那样 有没有办法让切割机使用分层数据结构来获得更好的性能 代码如下: #include <vtkSmartPointer.h> #include <vtkCubeSource.h> #include <vtkPolyDataMapper.h> #include <vtkPlane.h> #i

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

有没有办法让切割机使用分层数据结构来获得更好的性能

代码如下:

#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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
//解析命令行参数
如果(argc!=2){
std::cout GetOutputPort());
//创建一个要剪切的平面,在此平面沿XZ方向剪切(XZ法线=(1,0,0);XY=(0,0,1),YZ=(0,1,0)
vtkSmartPointer平面=vtkSmartPointer::New();
平面->设置原点(0,0,0);
平面->设置法线(1,0,0);
//创建切割器
vtkSmartPointer=vtkSmartPointer::New();
刀具->设置切削功能(平面);
刀具->设置输入连接(obj->GetOutputPort());
刀具->更新();
vtkSmartPointer cutterMapper=vtkSmartPointer::New();
cutterMapper->SetInputConnection(cutter->GetOutputPort());
//创建平面演员
vtkSmartPointer planeActor=vtkSmartPointer::New();
planeActor->GetProperty()->SetColor(1.0,1,0);
planeActor->GetProperty()->SetLineWidth(2);
planeActor->SetMapper(切割机);
//创建多维数据集参与者
vtkSmartPointer cubeActor=vtkSmartPointer::New();
cubeActor->GetProperty()->SetColor(0.5,1,0.5);
cubeActor->GetProperty()->SetOpacity(0.5);
cubeActor->SetMapper(映射器);
//创建渲染器并添加平面和立方体的角色
vtkSmartPointer=vtkSmartPointer::New();
renderer->AddActor(planeActor);//显示剪切产生的矩形
renderer->AddActor(cubeActor);//显示多维数据集
//将渲染器添加到renderwindow并渲染
vtkSmartPointer renderWindow=vtkSmartPointer::New();
renderWindow->AddRenderer(渲染器);
渲染窗口->设置大小(600600);
vtkSmartPointer=vtkSmartPointer<
vtkRenderWindowInteractor>::New();
交互器->设置渲染窗口(渲染窗口);
渲染器->设置背景(0,0,0);
renderWindow->Render();
交互器->开始();
返回退出成功;
}

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

  • 这些通用实现通常需要花费大量的CPU时间,因为在
    vtkCutter
    的情况下,所有多边形切割的特殊情况都会发生
  • 在VTK庞大的类层次结构中调用虚拟函数也会降低速度。如果没有特殊的破解,它完全依赖于编译器优化循环外的虚拟函数指针查找,而VTK在一个或多个嵌套循环中多次调用虚拟函数(例如,过滤函数)。 有关信息,请参见此:
  • VTK几乎在任何地方都使用
    double
    s,即使可以使用
    float
    s。转换和高精度也会增加少量计算和内存开销
  • VTK(5.8)未明确涉及SSE、afaik等SIMD操作
搜索以下主题:

尽管在CPU上这样做,但是也可以在转换反馈通道中使用OpenGL几何着色器来提取由切割平面确定的切割轮廓。在OpenCL中也可以这样做,但是,如果没有基于GPU的计算设备,它可能会比C或C++实现慢。 要渲染网格,可以使用任何支持OpenGL 3+的渲染器:

  • 一个简单的,自制的OpenGL 3渲染器

更多:

旁注:尽管我不想成为一个仇恨者,但每次我不得不处理这个邪恶的、过度设计的#¼%$@,我的良心都会大喊:“停下。现在,不要使用这个过度抽象、不推荐的GL,运行时容易出错的东西。”.老实说,出于好意:如果可以的话,现在就停止使用它。至少,更换渲染部分以创建未来验证软件。@Sam你建议他用什么来代替?@David Doria:问得好。On不应该像我上面那样添加注释,没有任何线索。我在回答中添加了一些想法。