[英]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: 在给定位置检索标量值的正确方法取决于两个问题:
Concerning the data layout there are two main layouts: 关于数据布局 ,主要有两种布局:
Concerning the position you can have two situations: 关于职位,您可以有两种情况:
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. 在这里,数据布局很重要。
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.