2016-02-13 45 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。
相關問題