如何对 vtk Poly Data 进行布尔运算?

How to do Boolean operations on vtk Poly Data?

我正在尝试计算两个 vtkPolyData by using the vtkBooleanOperationPolyDataFilter class. I read the only example provided in VTK examples website 之间的差异,并且我尝试使用它。

但是,我的问题有点不同,因为我有 .stl 文件。因此,首先我必须将 .stl 文件转换为 vtkPolyData。我正在使用函数 convert_stl_to_polydata() 执行此操作。然后,我使用 compute_difference() 计算差异并写入输出。

#include <string>
#include <vtkPolyData.h>
#include <vtkSmartPointer.h>
#include <vtkSTLReader.h>
#include <vtkUnstructuredGrid.h>
#include <vtkXMLUnstructuredGridWriter.h>
#include <vtkBooleanOperationPolyDataFilter.h>


vtkSmartPointer<vtkPolyData> convert_stl_to_polydata (std::string input) {
  auto stl_reader = vtkSmartPointer<vtkSTLReader>::New();
  stl_reader->SetFileName (input.c_str());
  stl_reader->Update();

  auto poly_data = vtkSmartPointer<vtkPolyData>::New();
  poly_data->ShallowCopy(stl_reader->GetOutput());
  return poly_data;
}


void compute_difference (vtkSmartPointer<vtkPolyData> input1,
                         vtkSmartPointer<vtkPolyData> input2, std::string output) {

  auto boolean_operation = vtkSmartPointer<vtkBooleanOperationPolyDataFilter>::New();
  boolean_operation->SetInputData (0, input1);
  boolean_operation->SetInputData (1, input2);
  boolean_operation->SetOperationToDifference();
  boolean_operation->Update();

  // write the result as an Unstructured Grid
  auto unstructured_grid = vtkSmartPointer<vtkUnstructuredGrid>::New();
  unstructured_grid->ShallowCopy(boolean_operation->GetOutput());

  auto writer = vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New();
  writer->SetFileName(output.c_str());
  writer->SetInputData(unstructured_grid);
  writer->SetDataModeToAscii();
  writer->Update();
  writer->Write();
}

int main () {
  std::string input1_filename {"Data/input_1.stl"};
  std::string input2_filename {"Data/input_2.stl"};
  std::string diff_filename {"Data/difference.vtu"};


  auto input1 = vtkSmartPointer<vtkPolyData>::New();
  auto input2 = vtkSmartPointer<vtkPolyData>::New();

  input1 = convert_stl_to_polydata(input1_filename);
  input2 = convert_stl_to_polydata(input2_filename);

  compute_difference (input1, input2, diff_filename);

  return 0;
}

第一个函数运行良好。但是,当我用 paraview 打开它时,第二个函数的输出文件是空的。有关更多信息,我正在使用 VTK 8.2.0.

问题

感谢任何改进代码的建议。

关于您的问题

  • 我不确定你为什么要将 boolean_operation->GetOutput() 传递给非结构化网格而不是 vtkPolyData

  • 在 vtk 中,您总是使用由 vtkPolyData 对象表示的多边形数据。

  1. 是的,您 vtkBooleanOperationPolyDataFilter 使用正确。
  2. vtkSTLReader 创建一个 vtkPolyData,这是布尔运算过滤器的正确输入容器。因此:是的,可以读取 STL 并立即用 vtkBooleanOperationPolyDataFilter.
  3. 处理它们

将输出从 vtkPolyData 转换为 vtkUnstructuredGrid 时,您丢失了一些信息。我认为浅拷贝只复制点,而不是单元格。您检查过以下内容吗?

std::cout << unstructured_grid->GetNumberOfCells() << std::endl;
std::cout << unstructured_grid->GetNumberOfPoints() << std::endl;

由于 vtkBooleanOperationPolyDataFilter 的输出是 vtkPolyData,无论如何将其转换为非结构化网格没有多大意义。

vtkUnstructuredGrid 通常用于表示体积网格,而您没有。 vtkPolyData 是表示表面网格的标准容器。


关于样式,我宁愿使用已经存在的智能指针来操作 reader 而不是为多边形数据创建一个新的智能指针。

vtkSmartPointer<vtkSTLReader> read_stl (std::string input) {
    auto stl_reader = vtkSmartPointer<vtkSTLReader>::New();
    stl_reader->SetFileName (input.c_str());
    stl_reader->Update();
    return stl_reader;
}

然后,将数据转发到布尔过滤器:

auto boolean_operation = vtkSmartPointer<vtkBooleanOperationPolyDataFilter>::New();
boolean_operation->SetInputConnection (0, input1->GetOutputPort());
boolean_operation->SetInputConnection (1, input2->GetOutputPort());
boolean_operation->SetOperationToDifference();
boolean_operation->Update();

只是一个建议。如果您还不知道该资源,请查找 here 大量示例。