【问题标题】:How to do Boolean operations on vtk Poly Data?如何对 vtk Poly Data 进行布尔运算?
【发布时间】:2020-02-11 10:51:33
【问题描述】:

我正在尝试使用 vtkBooleanOperationPolyDataFilter 类计算两个 vtkPolyData 之间的差异。我阅读了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 网格上使用布尔运算?

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

【问题讨论】:

    标签: c++ vtk


    【解决方案1】:
    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();
    

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

    【讨论】:

      【解决方案2】:

      关于您的问题

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

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

      【讨论】:

      • 感谢您的回复。我这样做是因为最后我想将差异运算的结果存储为非结构化网格。你有什么不同的建议吗?
      • 我认为您应该将其存储为 vtkPolyData (正如过滤器的名称所示..),至少我确定在这种情况下它可以工作:)
      • @mmusy 在 vtk 中仅使用 vtkPolyData 是不正确的。数据容器的最佳选择取决于问题的类型。 vtkPolyData 在使用表面网格时当然是一个不错的选择,但对于体积网格,人们更喜欢 vtkUnstructuredGrid。 vtk 也支持其他结构:图形、图像、点云、网格……
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-28
      • 2021-12-06
      • 1970-01-01
      • 2022-01-01
      • 2010-11-29
      • 2011-05-30
      • 1970-01-01
      相关资源
      最近更新 更多