Open3DをWindowsのC++で扱えるようにする

 諸事情からWindows環境でOpen3Dを扱う事になりました。Visual StudioのC++でOpen3DライブラリのAPIを叩けるまでの手順をまとめます。

Open3Dとは?

 Open3Dは3Dデータを扱うアプリケーションを迅速に作成するサポートをしてくれるオープンソースライブラリです。MITライセンスで商用でも使えます。特に3Dスキャニングした3D点群データを表示加工する際に便利な関数を多数取り揃えてくれています。

 ライブラリはPythonとC++のAPIを公開してくれています。大量のデータを扱う為エンジンはC++で作られていて、Pythonはライブラリをインストールして使う形式になっています。

記事のゴール

 本記事のゴールはWindows+Visual Studio 2019でOpen3DのC++APIを叩けるようになる事です。そのためにOpen3D.libおよびOpen3D.dllをソースからビルドし、それをプロジェクトに組み入れます。

 尚、執筆時点(2023.8)でのOpen3Dのバージョンは0.17.0です。今後バージョンアップに伴い下記の手順でうまく行かなくなる可能性もありますので予めご了承ください。

Open3Dのソースを入手&ビルドするたえのアプリをインストール

 Open3Dのソースを入手してビルドするには幾つかアプリケーションが必要になります。入手にはgitが、ビルドにはCMakeが必要です。

※実はビルド済みライブラリが本家Open3Dのサイト(http://www.open3d.org/)からダウンロード可能ではあるのですが、デバッグ版が提供されていないなどちょっと微妙でした…。色々試して結局ソースをgitクローンしてビルドするのが確実でした。

gitをインストール

 すでにgit環境がある方はここを飛ばしてOKです。git環境があるか調べるにはコマンドプロンプト(もしくはPower Shell)で「git」と入れてみて下さい。Usage云々が出た方はgit環境があります。「そんなの知らない~」と言われた方はgit環境がインストールされていません。

 gitというのは「バージョン管理ツール」という部類に入るアプリケーションで、プログラムなどの更新を保存管理しそれにバージョンを付記してくれます。これによりバージョンを指定する事でそのバージョン時のプログラム一式をごそっと取り出す事ができます。凄まじく便利なツールです。

 gitのインストーラーは以下のサイトからダウンロードできます:

最新版をダウンロードしてインストールすればOK。コマンドプロンプトでgitと叩いてインストールを確認して下さい。

CMakeをインストール

 gitでクローンしてきたC++ソースからlibとdllを作るにはコンパイル(ビルド)する必要があります。それを行ってくれるのがmakeという機構です。Open3DはCMakeというアプリを採用していますのでそれをインストールしましょう。

 以下のCMakeのダウンロードページ、

ここの、

Windows x64 installerをダウンロードしましょう。これは64bit版Windows用のCMakeのインストーラーです。ダウンロードしたインストーラーを実行すればインストールが始まります。途中で、

このようなInstall Option画面が出ます。CMakeのデフォルトディレクトリへのパスを環境変数に追加するかを尋ねています。これは追加を推奨します。環境変数にパスを追加するとコマンドラインで「cmake」と打つだけでどこからでもmake出来るようになります。all users(すべてのユーザーでcmakeを使えるようにする)かcurrent user(今ログインしているユーザーのみ使えるようにする)かはお使いの環境で決めて下さい。どちらを選んでも少なくとも貴方は使えますw

 インストールが終わったらコマンドプロンプトを立ち上げて「cmake」と打ってみましょう:

上のようにUsageが出てくればインストール&パスの設定ができています。

ビルド環境を整備

 Open3Dのビルド、割と複雑です(^-^;。なるべく見通しを良くするためにビルドをする専用のフォルダを作り、その下でビルドするようにします。

 アクセス可能な所に適当な空のルートフォルダを一つ作ってください。僕は「Open3D」というフォルダを作りました。最終的にこのルートフォルダの下にlibとdllが出来ます。

Open3Dソースをgitでダウンロード

 コマンドラインを起動し作成したルートフォルダへ行きます。そこにgitを使ってOpen3Dのソースをダウンロードします。以下のコマンドを入力してください:

git clone https://github.com/isl-org/Open3D open3d-0.17.0 -b v0.17.0 --depth 1

 これによりgithubにあるOpen3Dのサイトからv0.17.0バージョンのOpen3Dをダウンロードしてくれます。問題が無ければルート下に以下のフォルダが出来ているはずです:

ビルド専用フォルダを作成

 open3d-0.17.0フォルダ内に入ると沢山のフォルダが並んでいるのが分かると思います。そこにビルド生成物を出力する専用の「build」フォルダを追加しましょう。実際ビルドしてみると分かりますが凄まじい量の中間生成物が出力されるので、フォルダ分けしないと瞬でカオス化しちゃうんですね(^-^;

ビルドに必要なリソースをbuildフォルダ内にかき集める

 次にOpen3Dのビルドに必要なリソースをbuildフォルダ下にかき集めてきます。Open3Dは非常に沢山の機能が盛り込まれているのですが、すべての機能を必ずしも使う必要はありません。そのため使う機能だけを一度集めて、それをターゲットにビルドする必要があるんです。一手間多い感じですね。

 このかき集め作業はCMake のコマンドで実行する事が出来ます。必要な機能についてはCMakeを実行する際の引数で指定できます。コマンドラインでbuildフォルダに移動して、次のようなcmakeコマンドを実行します:

cmake -DBUILD_SHARED_LIBS=ON -DBUILD_EXAMPLES=OFF -DBUILD_PYTHON_MODULE=OFF -DBUILD_WEBRTC=OFF -DCMAKE_DEBUG_POSTFIX=d -DCMAKE_INSTALL_PREFIX="<Your Path>\Open3D" ..

 機能を取捨選択するためのフラグを指定する必要からコマンドが長くなってしまいます。フラグは-Dオプションで指定します。多分"D"efineの略ですね。

 Open3Dのmakeには多数のフラグが定義されていて正直把握しきれません(^-^;。今回設定した物のみ列挙して説明します。

○ BUILD_SHARED_LIBS
 Open3D.dllを作成するかを指定します。ONで作成、OFFで作成しないです。libのみの場合色々依存関係があって面倒なようなので、一まとめにしてくれるdllを作った方が使いやすいようです。

○ BUILD_EXAMPLES
  サンプルをビルドするか指定します。今回はOpen3D.libとOpen3D.dllを作る事が目的なのでサンプルビルドはOFFにしています。

○ BUILD_PYTHON_MODULE
 
ライブラリをPythonから利用できるようにするモジュールを作成するか指定します。今回はPythonは視野に入れていないのでOFFです。

○ BUILD_WEBRTC
 WebRTCというネットワークを介したモデルビューを可能にするかを指定します。今回はネットワーク関連は使わないのでOFFにしています。Open3DのWebRTC周りについてはドキュメントにあります:

○ CMAKE_DEBUG_POSTFIX
 作成されるlibやdllのデバッグ版に対して指定の接尾子を付けます。"d"とするとデバッグ版はOpen3Dd.libやOpen3Dd.dllとなります。実はOpen3D.libやdllはVisual StudioのDebugとReleaseとでライブラリを切り分けないとうまく動きません。そのためこのフラグは必須です。

○ CMAKE_INSTALL_PREFIX
 Open3D.libやdllの最終的な出力先となるフォルダを指定します。どこでも良いのですが今回作ったルートフォルダ直下で良いのかなと思います。

これでbuild下にビルドに必要なリソースが集められます。

尚、その他のフラグについてはルートフォルダ下にあるCMakeLists.txtというmake内容が記述されたテキストファイルに記載がありますのでご参照下さい。

Open3Dライブラリをビルド

Debug版をビルド

 buildフォルダ下に必要なリソースが揃ったら、コマンドプロンプトでbuildフォルダに移動して、以下のビルド用のcmakeを叩きます:

cmake --build . --config Debug --target ALL_BUILD

これでDebug版のビルドが走ります。このビルド、1時間程かかります!叩く際はタイミングにご注意を。しかもDebug版ビルドは次のようなエラーが出て最初は失敗します:

これはビルドで作成されたbulid/lib/glfw3d.libというライブラリの名前が原因です。ビルドプロセスの中で「glfw3.lib」という名前である前提になっているみたいです。よってこのライブラリをglfw3.libと"d"を除いた名前にリネームしてもう一度ビルドコマンドを叩くと先へ進みます:

ビルドが終了すると、build/libフォルダにOpen3Dd.libと各種libファイルが、build/bin/DebugフォルダにOpen3Dd.dllが作成されています!「よっしゃ、これをコピればもう使えるじゃん!」と思う所ですが、libを使うにはヘッダーファイル群が必要です。今それが無いんですね。それを含めてlibやdllをプログラムで使えるように整えてくれるのがINSTALLです。

 ビルド終了後にbuildフォルダ下で次のコマンドを叩いて下さい:

cmake --build . --config Debug --target INSTALL

 これによりOpen3Dルートフォルダ直下に次のようなフォルダ群が出来ます:

libフォルダ下にOpen3D.lib、binフォルダ下にOpen3D.dll、そしてinclude下にopen3dで使用するヘッダーファイル群が揃っています。これでDebug版でOpen3DのAPIを叩く事がようやく出来るようになりました!!

Release版をビルド

 先にも注意したのですが、Open3DはDebug版とRelease版でlibやdllを明確に区別してリンクする必要があります。製品に組み込む時はもちろんRelease版を使うわけですが、開発中はターゲットをDebugにしますよね。この時Release版のlibとdllを使うと例外で落ちます。これ最初意味が分からずに「何で例外出るねん!」と頭を抱えました…。

 という事でRelease版もビルドするのですが、すでにbuild/libフォルダにはDebug版のlib群が並んでいますので、libフォルダをlib_debugなどとリネームしてRelease版と混ざらないようにします。

 後はDebug版のコマンドと同じです。ただし「Debug」としていた所を「Release」に差し替えて下さい:

cmake --build . --config Release --target ALL_BUILD
cmake --build . --config Release --target INSTALL

このビルドも小1時間程かかりますので、まぁYouTubeでも見て時間を潰して下さいw。INSTALLするとOpen3Dルートフォルダ下のlibとbinにRelease版のOpen3D.libとdllがそれぞれ格納されます。やっとライブラリが揃いました!

Open3D.libとOpen3D.dllを使ってみよう!

 ようやく出来たlibとdllを使ってAPIを叩いてみましょう。

テスト環境作成

 Visual Studio 2019を起動して、適当なC++プロジェクトを立ち上げます。ピュアな状態でテストしたいので空のプロジェクトにしておきましょうか。プロジェクトが起動したらエントリーとなるmain関数を定義するためmain.cppを追加して下さい。そこにmain関数を作ればエントリーになります:

次にプロジェクトのフォルダ下にlibとdllそしてヘッダーファイルが入ったopen3dフォルダをコピーしてきます:

これを使うのが本来の目的ですものね(^-^;

 続いてコピーしてきたOpen3Dライブラリをリンクするためにプロジェクトのプロパティを設定します:

[リンカー]の[追加の依存ファイル]にOpen3D.lib(Debugの場合はOpen3Dd.lib)を指定します。

またヘッダー群へのパスも追加します:

[C/C++]の[全般]にある[追加のインクルードディレクトリ]にopen3dへのパスを追加します。追加するのはopen3dフォルダと、その子にある3rdpartyフォルダです。

 これでmain.cppにOpen3d.hをインクルードしてみましょう:

#include <Open3D.h>

int main() {
	return 0;
}

ビルドしてエラーが出なければライブラリとのリンクは成功です。

APIを叩いてみる

 APIの呼び出しがうまく行くかテストするため、main.cppでOpen3DのPLYPointCloudクラスのオブジェクトを作成してみましょう:

#include <Open3D.h>

int main() {
	auto cloudData = std::make_shared< open3d::data::PLYPointCloud >();
	return 0;;
}

PLYPointCloudオブジェクトはサンプルデータの一つで、下のような部屋を3Dスキャナでサンプリングした点群データになっています。データ形式はplyです:

上のコードを初回実行するとコンソールにgitからリソースをダウンロードした旨のメッセージが出ます:

上のデータが存在しないのでわざわざダウンロードしてきてくれたんですね。該当のplyファイル(fragment.ply)はUsersフォルダ下のご自身のユーザー名フォルダ下にopen3d_dataというフォルダが出来て、そこに格納されます。2回目以降の起動ではダウンロード済みのplyファイルを読み込むのでダウンロード工程はスキップされます。

 PLYPointCloudオブジェクトを作成出来てダウンロードも走るというのはAPIが正常に動作している証拠です。これでC++でOpen3DライブラリのAPIを叩ける事がわかりました!

終わりに

 今回はOpen3DをVisual StudioでC++環境で使うためにソースビルドする方法を見て来ました。ビルド構成や流れが理解できれば何とかなるとはいえ、無から始めるには中々に導入ハードルが高いかなと個人的には思いました。導入方法で困っている方の一助になれれば幸いです。

ではまた(^-^)/

この記事が気に入ったらサポートをしてみませんか?