如何对 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.
问题
- 我是否正确使用了 vtkBooleanOperationPolyDataFilter?
- 是否可以直接在 STL 网格上使用布尔运算?
感谢任何改进代码的建议。
关于您的问题
我不确定你为什么要将 boolean_operation->GetOutput()
传递给非结构化网格而不是 vtkPolyData
在 vtk 中,您总是使用由 vtkPolyData
对象表示的多边形数据。
- 是的,您
vtkBooleanOperationPolyDataFilter
使用正确。
vtkSTLReader
创建一个 vtkPolyData
,这是布尔运算过滤器的正确输入容器。因此:是的,可以读取 STL 并立即用 vtkBooleanOperationPolyDataFilter
. 处理它们
将输出从 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 大量示例。
我正在尝试计算两个 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.
问题
- 我是否正确使用了 vtkBooleanOperationPolyDataFilter?
- 是否可以直接在 STL 网格上使用布尔运算?
感谢任何改进代码的建议。
关于您的问题
我不确定你为什么要将
boolean_operation->GetOutput()
传递给非结构化网格而不是vtkPolyData
在 vtk 中,您总是使用由
vtkPolyData
对象表示的多边形数据。
- 是的,您
vtkBooleanOperationPolyDataFilter
使用正确。 vtkSTLReader
创建一个vtkPolyData
,这是布尔运算过滤器的正确输入容器。因此:是的,可以读取 STL 并立即用vtkBooleanOperationPolyDataFilter
. 处理它们
将输出从 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 大量示例。