简体   繁体   English

x,y,z点的vtk值

[英]vtk value at x,y,z point

I have a vtk file which maps temperature in 3 dimensions. 我有一个vtk文件,可将温度映射为3维。 I would like to determine the temperature at a given x, y, z point. 我想确定给定x,y,z点的温度。 I will use the following code in order to load the vtk file ( Reading .vtk file ): 我将使用以下代码来加载vtk文件( 读取.vtk文件 ):

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;
}

However, when searching through the extensive list of methods in the vtk library I cant find the appropriate function to extract a value at a specific location. 但是,当在vtk库中搜索大量方法时,我找不到合适的函数来提取特定位置的值。 Any suggestions? 有什么建议么?

The proper way to retrieve a scalar value at a given position depends on two questions: 在给定位置检索标量值的正确方法取决于两个问题:

  1. How is your data laid out and 您的数据如何布置以及
  2. From which position do you want to retrieve an attribute 您要从哪个位置检索属性

Concerning the data layout there are two main layouts: 关于数据布局 ,主要有两种布局:

  • Structured: The data resides in a uniform grid 结构化:数据驻留在统一的网格中
  • Unstructured: The point samples are arbitrary 非结构化:点样本是任意的

Concerning the position you can have two situations: 关于职位,您可以有两种情况:

  • Query at a sample position: You ask for a point that is directly a sample in your dataset 在样本位置进行查询:您要求的点直接是数据集中的样本
  • Query at an arbitrary position: You ask for a point that is somewhere in your domain but does not neccessarily coincide with a sample of your data. 在任意位置查询:您要求的点在您的域中某处,但不一定与数据样本一致。

Independent of the data layout, to retrieve the data at a sample position (ie a sample of your original data set) you can use the vtkPointLocator class. 与数据布局无关,要在示例位置(即原始数据集的示例)检索数据,可以使用vtkPointLocator类。 Use the class as follows (untested): 使用以下类(未经测试):

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

This will give you the point value of the closest sample of your data. 这将为您提供最接近的数据样本的点值。 Note that this will not give you the explicit position of the point in the data set as this is implicitly encoded in the variable id . 请注意,这不会为您提供该点在数据集中的明确位置,因为它是隐式编码在变量id中的 To retrieve the actual position of the closest point, you can write: 要检索最接近点的实际位置,可以编写:

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

If you want to retrieve data at an arbitrary position of your domain you will need some way of interpolation. 如果要在域的任意位置检索数据,则需要某种插值方式。 Here, the data layout is important. 在这里,数据布局很重要。

  • For structured data you can first convert your data to a vtkImage and then perform queries on it. 对于结构化数据,您可以先将数据转换为vtkImage,然后对它执行查询。 If you want to retrieve an interpolated attribute using linear or cubic schemes you can add a vtkImageInterpolator in your filter chain and then retrieve a point using the GetScalarComponentAsDouble method. 如果要使用线性或三次方案检索插值属性,可以在过滤器链中添加vtkImageInterpolator,然后使用GetScalarComponentAsDouble方法检索点。
  • For unstructured data you should first decide on an interpolation scheme. 对于非结构化数据,您应该首先确定插值方案。 vtk has various filters to reconstruct continuous data from data samples. vtk具有各种过滤器,可从数据样本中重建连续数据。 Options include Delaunay triangulation/tetrahedrization (vtkDelaunay2D, vtkDelaunay3D) , as well as the Shepard method (vtkShepardMethod). 选项包括Delaunay三角剖分/四面体化(vtkDelaunay2D,vtkDelaunay3D)以及Shepard方法(vtkShepardMethod)。 Either method will give you a new data set with possibilities to query arbitrary points. 两种方法都可以为您提供一个新的数据集,并可以查询任意点。 If you want to retrieve the scalar attributes for a (batch of) points without actually reconstructing a complete data set you can also look at the vtkProbeFilter. 如果要检索(一批)点的标量属性而没有实际重建完整的数据集,则还可以查看vtkProbeFilter。

You need to first extract the polyData from the reader. 您需要首先从阅读器中提取polyData。 Then, store the points via vtkPolyData::getPoints into a vtksmartPointer<vtkPoints> . 然后,通过vtkPolyData::getPoints将这些点存储到vtksmartPointer<vtkPoints> To finish, create a std::vector of a custom struct and store them while iterating over your vtkPoints. 最后,创建一个自定义结构的std::vector并在遍历vtkPoints的同时存储它们。

Here's some code to illustrate : 这是一些代码来说明:

#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;
}

And here is the version with the vtkPointLocator mentionned in QnD's answer : 这是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;
}

And the CMakeLists.txt 还有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()

Please let me know if I need to do any specific action to correctly credit the other answer. 如果需要采取任何具体措施来正确记入其他答案,请告诉我。 I'm new and don't know all the specifics yet. 我是新手,尚不了解所有细节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM