如何在 vtk Poly 数据上进行布尔运算?

How to do Boolean operations on vtk Poly Data?

本文关键字:布尔运算 数据 vtk Poly      更新时间:2023-10-16

我正在尝试使用 vtkBooleanOperationPolyDataFilter 类计算两个 vtkPolyData 之间的差异。我阅读了VTK示例网站中提供的唯一示例,并尝试使用它。

但是,我的问题有点不同,因为我有 .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。

问题

  • 我是否正确使用了 vtkBooleanOperationPolyDataFilter?
  • 是否可以直接在 STL 网格上使用布尔运算?

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

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

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

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

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

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


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

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();

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

关于您的问题

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

  • 在 VTK 中,您始终使用由vtkPolyData对象表示的多边形数据。