介紹如何從原始碼自行編譯安裝 OpenVDB 函式庫,並編譯一個 hello world 程式。
OpenVDB 是一套開放原始碼的 C++ 函式庫,提供高效能的三維立體資料(volumetric data)儲存結構與處理工具,以下是 OpenVDB 函式庫的安裝、使用教學與範例。
編譯與安裝 OpenVDB 函式庫
若在 Ubuntu Linux 系統上,可以使用 apt
安裝編譯 OpenVDB 的必要套件:
# 安裝必要套件 sudo apt-get install -y libboost-iostreams-dev libboost-system-dev \ libtbb-dev libilmbase-dev libopenexr-dev libblosc-dev
另外有一些選擇性套件也可以順便安裝:
# 安裝選擇性套件
sudo apt install libboost-all-dev libjemalloc-dev
若在其他系統中,則可參考 OpenVDB 官方的說明。
接著從 GitHub 網站下載 OpenVDB 最新的原始碼:
# 下載 OpenVDB 原始碼
git clone https://github.com/AcademySoftwareFoundation/openvdb.git
建立編譯用目錄,以 CMake 進行編譯並且安裝:
# 編譯 OpenVDB mkdir build cd build cmake ../openvdb make -j4 # 安裝 OpenVDB sudo make install
這樣就完成基本的 OpenVDB 函式庫的安裝了。若需要自訂一些編譯選項,可以參考 OpenVDB 的編譯說明。
Hello World 範例
參考 OpenVDB 官方文件的範例,建立一個 C++ 檔案 hello.cpp
,內容如下:
#include <openvdb/version.h> #include <openvdb/openvdb.h> #include <iostream> int main() { // 顯示 OpenVDB 版本 std::cout << "OpenVDB " << openvdb::OPENVDB_LIBRARY_MAJOR_VERSION << "." << openvdb::OPENVDB_LIBRARY_MINOR_VERSION << "." << openvdb::OPENVDB_LIBRARY_PATCH_VERSION << std::endl; // 初始化 OpenVDB 函式庫(至少必須執行一次,執行多次無妨) openvdb::initialize(); // 建立一個 grid,預設值皆為背景值 0 openvdb::FloatGrid::Ptr grid = openvdb::FloatGrid::create(); std::cout << "測試隨機存取:" << std::endl; // 取得以座標為基礎的 Accessor openvdb::FloatGrid::Accessor accessor = grid->getAccessor(); // 以有號索引定義座標 openvdb::Coord xyz(1000, -200000000, 30000000); // 設定 (1000, -200000000, 30000000) 的 voxel 值為 1.0 accessor.setValue(xyz, 1.0); // 讀取 (1000, -200000000, 30000000) 座標位置的值 std::cout << "Grid" << xyz << " = " << accessor.getValue(xyz) << std::endl; // 重新設定座標位置 xyz.reset(400, 5000, -600); // 讀取 (400, 5000, -600) 座標位置的值 std::cout << "Grid" << xyz << " = " << accessor.getValue(xyz) << std::endl; // 設定 (400, 5000, -600) 的 voxel 值為 2.0 accessor.setValue(xyz, 2.0); // 測試座標系統中最極端的位置 // 以 32 位元有號座標系統來說,最極端的位置就是 (-2147483648, -2147483648, -2147483648) // 與 (2147483647, 2147483647, 2147483647) accessor.setValue(openvdb::Coord::min(), 3.0f); accessor.setValue(openvdb::Coord::max(), 4.0f); std::cout << "測試連續存取:" << std::endl; // 列出所有被啟用的 voxels for (openvdb::FloatGrid::ValueOnCIter iter = grid->cbeginValueOn(); iter; ++iter) { std::cout << "Grid" << iter.getCoord() << " = " << *iter << std::endl; } }
使用 g++
編譯使用 OpenVDB 函式庫的應用程式,連結時要加上一些必要的函式庫:
# 編譯 OpenVDB 程式 g++ -o hello hello.cpp -ltbb -lopenvdb -lHalf
在執行 OpenVDB 的應用程式之前,要先以 LD_LIBRARY_PATH
設定好 libopenvdb.so
所在位置:
# 設定 libopenvdb.so 所在位置 export LD_LIBRARY_PATH=/usr/local/lib/
執行編譯好的 OpenVDB 應用程式:
./hello
OpenVDB 7.1.0 測試隨機存取: Grid[1000, -200000000, 30000000] = 1 Grid[400, 5000, -600] = 0 測試連續存取: Grid[-2147483648, -2147483648, -2147483648] = 3 Grid[1000, -200000000, 30000000] = 1 Grid[400, 5000, -600] = 2 Grid[2147483647, 2147483647, 2147483647] = 4
CMake 編譯 OpenVDB 應用程式
若要以 CMake 編譯 OpenVDB 應用程式,可以參考以下 CMakeLists.txt
,但目前測試有小 bug:
cmake_minimum_required(VERSION 3.3) set(CMAKE_VERBOSE_MAKEFILE ON) list(APPEND CMAKE_MODULE_PATH "/usr/local/lib/cmake/OpenVDB") find_package(OpenVDB REQUIRED) add_executable(hello hello.cpp) target_link_libraries(hello OpenVDB::openvdb)
參考資料:Juraj Tomori