介紹如何使用 VTK 與 OpenVDB 將 VTK ImageData 格式的三維立體影像轉換為 VDB 格式。
若要將 VTK ImageData 格式(*.vti
檔案)的三維立體影像(volume image)轉換為 VDB 格式,使用 VTK 函式庫讀取影像之後,然後再使用 OpenVDB 函式庫轉為 VDB 的檔案格式,以下是基本的實作程式碼。
#include <vtkSmartPointer.h> #include <vtkImageData.h> #include <vtkPointData.h> #include <vtkXMLImageDataReader.h> #include <vtkFloatArray.h> #include <openvdb/openvdb.h> #include <string> #include <iostream> int main(int argc, char* argv[]) { std::string input = argv[1]; std::string output = argv[2]; // ----------------------- // // 以 VTK 讀取三維立體影像 // // ----------------------- // // 讀取影像 auto reader = vtkSmartPointer<vtkXMLImageDataReader>::New(); reader->SetFileName(input.data()); reader->Update(); vtkSmartPointer<vtkImageData> vtkImage = reader->GetOutput(); // 基本影像資訊 auto dims = vtkImage->GetDimensions(); std::cout << "Dimensions = " << dims[0] << " " << dims[1] << " " << dims[2] << std::endl; std::cout << "Scalar Type = " << vtkImage->GetScalarTypeAsString() << std::endl; std::cout << "Number Of Scalar Components = " << vtkImage->GetNumberOfScalarComponents() << std::endl; // -------------------------------------- // // 以 OpenVDB 將三維立體影像轉為 VDB 格式 // // -------------------------------------- // // 初始化 OpenVDB 函式庫(至少必須執行一次,執行多次無妨) openvdb::initialize(); // 建立一個 grid,預設值皆為背景值 0 openvdb::FloatGrid::Ptr grid = openvdb::FloatGrid::create(); // 設定 grid 的 class 為水平集 grid->setGridClass(openvdb::GRID_LEVEL_SET); // 設定 grid 名稱 grid->setName("density"); // 取得以座標為基礎的 Accessor openvdb::FloatGrid::Accessor accessor = grid->getAccessor(); // 以有號索引定義座標 openvdb::Coord xyz; // 從 VTK 影像轉換至 VDB grid int &x = xyz[0], &y = xyz[1], &z = xyz[2]; for (z = 0; z < dims[2]; ++z) { for (y = 0; y < dims[1]; ++y) { for (x = 0; x < dims[0]; ++x) { float value = vtkImage->GetScalarComponentAsFloat(x, y, z, 0); accessor.setValue(xyz, value); } } } // 輸出 VDB 檔案 openvdb::io::File(output.data()).write({grid}); return EXIT_SUCCESS; }
將以上的 C++ 程式碼儲存為 vdb_conv.cpp 之後,還要配合以下的 CMakeLists.txt 設定檔才能編譯。
CMakeLists.txt
設定檔由於這個程式需要同時使用到 VTK 與 OpenVDB,因此在 CMakeLists.txt
設定檔中就要引入這兩套函式庫,基本的設定內容如下:
cmake_minimum_required(VERSION 3.10.2) # 設定專案名稱 project (VDBConv) # 尋找並引入 VTK 函式庫 find_package(VTK REQUIRED) include(${VTK_USE_FILE}) # 尋找並引入 OpenVDB 函式庫 list(APPEND CMAKE_MODULE_PATH "/usr/local/lib/cmake/OpenVDB") find_package(OpenVDB REQUIRED) # 增加一個執行檔 add_executable(VDBConv vdb_conv.cpp) # 定義執行檔連結方式 target_link_libraries(VDBConv ${VTK_LIBRARIES} OpenVDB::openvdb)
準備好 vdb_conv.cpp
這個 C++ 原始碼與 CMakeLists.txt
設定檔之後,按照一般 CMake 專案的方式編譯:
# 建立編譯目錄 mkdir build # 編譯專案 cd build cmake .. make
編譯完成之後,即可使用此程式將 VTK 格式的三維立體影像轉為 VDB 檔案了:
# 執行程式
./VDBConv input.vti output.vdb
參考資料:Blender Artists