x,y,z点的vtk值

时间:2016-02-13 10:34:57

标签: c++ vtk

我有一个vtk文件,可以将温度映射到3个维度。我想确定给定的x,y,z点的温度。我将使用以下代码加载vtk文件(Reading .vtk file):

int main(int argc, char *argv[]) 
{
  // simply set filename here (oh static joy)
  std::string inputFilename = "setYourPathToVtkFileHere";

  // Get all data from the file
  vtkSmartPointer<vtkGenericDataObjectReader> reader =
        vtkSmartPointer<vtkGenericDataObjectReader>::New();
  reader->SetFileName(inputFilename.c_str());
  reader->Update();

  // All of the standard data types can be checked and obtained like this:
  if (reader->IsFilePolyData()) 
  {
    std::cout << "output is a polydata" << std::endl;
    vtkPolyData* output = reader->GetPolyDataOutput();
    std::cout << "output has " << output->GetNumberOfPoints() << "     points." << std::endl;
  }

  return EXIT_SUCCESS;
}

但是,在vtk库中搜索大量方法时,我无法找到在特定位置提取值的相应函数。有什么建议吗?

2 个答案:

答案 0 :(得分:5)

在给定位置检索标量值的正确方法取决于两个问题:

  1. 您的数据如何布局
  2. 您想从哪个位置检索属性
  3. 关于数据布局,有两种主要布局:

    • 结构化:数据位于统一网格
    • 非结构化:点样本是任意的

    关于职位,您可以有两种情况:

    • 在示例位置查询:您要求的数据点直接是数据集中的样本
    • 在任意位置查询:您要求某个点位于您域中的某个位置,但不一定与您的数据样本一致。

    独立于数据布局,要在样本位置检索数据(即原始数据集的样本),您可以使用vtkPointLocator类。使用如下(未经测试)的类:

    // Build locator object
    vtkSmartPointer<vtkPointLocator> locator = vtkPointLocator::New();
    locator->SetDataSet(polyData);
    locator->BuildLocator();
    // Define query position
    double pt[3] = {0.1, 0.2, 0.3};
    // Get the ID of the point that is closest to the query position
    vtkIdType id = locator->FindClosestPoint(pt);
    // Retrieve the first attribute value from this point
    double value = polyData->GetPointData()->GetScalars()->GetTuple(id, 0);
    

    这将为您提供最接近的数据样本的分值。 请注意,这不会为您提供数据集中该点的显式位置,因为它在变量id 中隐式编码。要检索最近点的实际位置,您可以写:

    double *dataPt = polyData->GetPoint(id);
    

    如果要在域的任意位置检索数据,则需要某种插值方式。 这里,数据布局很重要。

    • 对于结构化数据,您可以先将数据转换为vtkImage,然后对其执行查询。如果要使用线性或立方体方法检索插值属性,可以在过滤器链中添加vtkImageInterpolator,然后使用GetScalarComponentAsDouble方法检索点。
    • 对于非结构化数据,您应首先确定插值方案。 vtk具有各种过滤器,用于从数据样本重建连续数据。选项包括Delaunay三角剖分/四面体化(vtkDelaunay2D,vtkDelaunay3D),以及Shepard方法(vtkShepardMethod)。这两种方法都会为您提供一个新的数据集,可以查询任意点。如果要在不实际重建完整数据集的情况下检索(批次)点的标量属性,还可以查看vtkProbeFilter。

答案 1 :(得分:1)

您需要先从阅读器中提取polyData。然后,通过vtkPolyData::getPoints将积分存储到vtksmartPointer<vtkPoints>。 要完成,请创建std::vector自定义结构并在迭代vtkPoints时存储它们。

以下是一些代码来说明:

#include <vtkDataArray.h>
#include <vtkDataSet.h>
#include <vtkGenericDataObjectReader.h>
#include <vtkPointLocator.h>
#include <vtkPointData.h>
#include <vtkPolyData.h>
#include <vtkSmartPointer.h>
#include <vtkStructuredGrid.h>
#include <string>


struct Pnt {
    double x_, y_, z_;
    Pnt(double x, double y, double z) : x_(x), y_(y), z_(z) {}
};

    int main ( int argc, char *argv[] )
{
  // Ensure a filename was specified
  if(argc != 2)
    {
    std::cerr << "Usage: " << argv[0] << " InputFilename" << endl;
    return EXIT_FAILURE;
    }

  // simply set filename here (oh static joy)
  std::string inputFilename = "setYourPathToVtkFileHere";

  // Get all data from the file
  vtkSmartPointer<vtkGenericDataObjectReader> reader = vtkSmartPointer<vtkGenericDataObjectReader>::New();
  reader->SetFileName(inputFilename.c_str());
  reader->Update();

  vtkSmartPointer<vtkPolyData> polydata = reader->GetPolyDataOutput();
  vtkSmartPointer<vtkPoints> vtk_points = polydata->GetPoints();

  std::vector<Pnt> my_points;
  for (int i = 0; i < vtk_points->GetNumberOfPoints(); i++){
      const auto pnt = vtk_points->GetPoint(i);
      my_points.emplace_back(pnt[0], pnt[1], pnt[2]);
  }

  return EXIT_SUCCESS;
}

以下是QnD答案中提到的vtkPointLocator版本:

int main(int argc, char *argv[])
{
    // Ensure a filename was specified
    if (argc != 2)
    {
        std::cerr << "Usage: " << argv[0] << " InputFilename" << endl;
        return EXIT_FAILURE;
    }

    // simply set filename here (oh static joy)
    std::string inputFilename = "setYourPathToVtkFileHere";

    // Get all data from the file
    vtkSmartPointer<vtkGenericDataObjectReader> reader = vtkSmartPointer<vtkGenericDataObjectReader>::New();
    reader->SetFileName(inputFilename.c_str());
    reader->Update();

    vtkSmartPointer<vtkPolyData> polydata = reader->GetPolyDataOutput();

    //Building locator
    vtkSmartPointer<vtkPointLocator> locator = vtkPointLocator::New();
    locator->SetDataSet(polydata);
    locator->BuildLocator();

    //Finding point
    const double pt[3] = { 0.1, 0.2, 0.3 };
    vtkIdType id = locator->FindClosestPoint(pt);
    double pnt_found[3];
    polydata->GetPointData()->GetScalars()->GetTuple(id, pnt_found);

    return EXIT_SUCCESS;
}

和CMakeLists.txt

cmake_minimum_required(VERSION 2.8)

PROJECT(GenericDataObjectReader)

find_package(VTK REQUIRED)
include(${VTK_USE_FILE})

add_executable(GenericDataObjectReader MACOSX_BUNDLE GenericDataObjectReader)

if(VTK_LIBRARIES)
  target_link_libraries(GenericDataObjectReader ${VTK_LIBRARIES})
else()
  target_link_libraries(GenericDataObjectReader vtkHybrid vtkWidgets)
endif()

如果我需要采取任何具体措施来正确归功于其他答案,请告知我们。我是新人,还不知道所有细节。