2016-02-13 134 views
0

我有一个vtk文件,它可以将温度映射到三维空间。我想确定一个给定的x,y,z点的温度。我将使用下面的代码以加载vtk文件(Reading .vtk file):在x,y,z点的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; 
} 

然而,通过在vtk库方法的广泛列表搜索时,我无法找到相应的功能在提取值具体位置。有什么建议么?

回答

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

这里是版本与vtkPointLocator在QND的回答mentionned:

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() 

请让我知道我是否需要采取任何具体行动来正确评价其他答案。我是新的,并不知道所有的细节。

+0

cmake CMakeLists.txt – DrWales

+0

谢谢dutiona。如果下面的后续问题是无意识的,我很抱歉,但我是VTK库的一个新手。我已经尝试了下面的代码并制作方法(以及一些变体),但仍然收到编译错误。我假设我没有在CMakeLists.txt文件中包含正确的标题或添加正确的库。 – DrWales

+0

嗨,我会尽量花一些时间在工作中充分写出一个实际的例子。我没有在家编译vtk,这需要花费很多时间。 – dutiona

3

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

  1. 如何布置你的数据和
  2. 从哪个位置你要检索的属性

关于数据布局有两个主要的布局:

  • 结构:该数据驻留在一个均匀网格
  • 非结构化:点样是任意

关于位置可以有两种情况:在一个样本位置

  • 查询:您要求直接在您的数据集中存在样本的点
  • 在任意位置进行查询:您要求在您的域中的某个点处进行查询,但并不一定与sam一致您的数据。

独立的数据布局,以获取一个样本位置(即您的原始数据集的样本),您可以使用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。
相关问题