macOS: Visual Studio CodeでBlenderの開発環境を構築する
はじめに
Blender開発者によるライブコーディングを観ていると、Visual Studio Codeがとても便利そうでした。 そこで、macOSにてVisual Studio Code(以下VSCode)でBlenderの開発環境を構築してみます。
手順
こちらのマニュアルを参考にしました。 https://wiki.blender.org/wiki/Developer_Intro/Environment/Portable_CMake_VSCode
VS Codeのインストール
VSCodeを本家からダウンロードしてインストールします。 zipファイルを展開して、アプリケーションにコピーします。
拡張のインストール
本家のマニュアルに列挙されている拡張をインストールします。
- C/C++ (ms-vscode.cpptools)
- Python (ms-python.python)
- CMake (twxs.cmake)
- Git Lens (eamodio.gitlens)
- Explicit Folding (zokugun.explicit-folding)
フォーマッタの設定
Code > Preferences > Settingsを開きます。 検索フォームに「format」と入力し、「Editor: Default Formatter」の設定で、「ms-vscode.cpptools 」を選択します。
インテリセンスの設定
本家のマニュアルを読むと少し面倒な工程が必要そうです。 まずは、ビルドとデバッグをできるように整えたいので、ここではこの工程はスキップします。
Blenderのビルド
tasks.jsonに以下を設定し、ビルドを実行します。
{ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "2.0.0", "tasks": [ { "label": "Build Blender", "type": "shell", "command": "make", "group": "build" } ] }
Blenderのデバッグ版のビルド
前のステップでBlenderをビルドするとbuild_darwinというディレクトリ以下に様々なファイルが作成されます。
build_darwin/CMakeCache.txtにあるCMAKE_BUILD_TYPE
のRelease
をDebug
に変更します。
その後、VSCodeからビルドを実行します。
CMAKE_BUILD_TYPE:STRING=Debug
デバッガの設定
VSCodeからデバッグできるように、launch.jsonを以下のように記述します。
{ // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "(lldb) Launch Blender", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/../build_darwin/bin/Blender.app/Contents/MacOS/Blender", "args": [], // You could place a .blend file path here to open it by default, or any other Blender args "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": false, // This could be set to true if you prefer an external console for debugging "MIMode": "lldb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ], "preLaunchTask": "Build Blender" // Optional; you can use if you want it to build before launching } ] }
本家はLinux向けなので注意が必要です。 macOS向けに以下の修正を加えます。
ポイント
デバッグの実行
VSCodeで適当な場所にブレークポイントを設定します。
ここでは、Blenderを起動したら必ず実行される、void OVERLAY_extra_cache_init(OVERLAY_Data *vedata)
の関数の先頭に設定することにします。
Runから「(lldb) Launch Blender」をクリックしてデバッグを実行します。 launch.jsonのpreLaunchTaskに「Build Blender」を指定したので、Blenderのビルド後、デバッガが起動します。
実験: ワイヤーフレームの色を変更してみる
はじめに
今回は、Blenderのワイヤーフレームの色をHackして変更してみます。 GLSL(OpenGL Shading Language)の知識が役に立ちました。
使用したコード
master (2.93.0)を使用しました。 https://developer.blender.org/rBd447bd3e4a9a793364b5f4951ad280fe0293d79e
ワイヤーフレームが描画される仕組み
頂点シェーダとフラグメントシェーダでモデルのワイヤーフレームが描画されます。
頂点シェーダで定義されているfinalColor
にワイヤーフレームの色がセットされて、フラグメントシェーダでfinalColor
を参照して最終的な色(fragColor
)にセットされます。
source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl
out vec4 finalColor; [...] void main() { [...] vec3 rim_col, wire_col; if (isObjectColor || isRandomColor) { wire_object_color_get(rim_col, wire_col); } else { wire_color_get(rim_col, wire_col); } facing = clamp(abs(facing), 0.0, 1.0); /* Do interpolation in a non-linear space to have a better visual result. */ rim_col = pow(rim_col, vec3(1.0 / 2.2)); wire_col = pow(wire_col, vec3(1.0 / 2.2)); vec3 final_front_col = mix(rim_col, wire_col, 0.35); finalColor.rgb = mix(rim_col, final_front_col, facing); finalColor.rgb = pow(finalColor.rgb, vec3(2.2)); finalColor.a = wireOpacity; finalColor.rgb *= wireOpacity; }
source/blender/draw/engines/overlay/shaders/wireframe_frag.glsl
in vec4 finalColor;
[...]
void main()
{
[...]
fragColor = finalColor;
ちなみに、wireframe_vert.glsl
やwireframe_frag.glsl
はビルド時に、const char[]
型のdatatoc_wireframe_vert_glsl
とdatatoc_wireframe_frag_glsl
にそれぞれ変換されるようです。
そして、OVERLAY_shader_wireframe()
でシェーダープログラムとしてロードされます。
source/blender/draw/engines/overlay/overlay_shader.c
GPUShader *OVERLAY_shader_wireframe(bool custom_bias) { const DRWContextState *draw_ctx = DRW_context_state_get(); const GPUShaderConfigData *sh_cfg = &GPU_shader_cfg_data[draw_ctx->sh_cfg]; OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->wireframe[custom_bias]) { sh_data->wireframe[custom_bias] = GPU_shader_create_from_arrays({ .vert = (const char *[]){sh_cfg->lib, datatoc_common_view_lib_glsl, datatoc_common_globals_lib_glsl, datatoc_gpu_shader_common_obinfos_lib_glsl, datatoc_wireframe_vert_glsl, NULL}, .frag = (const char *[]){datatoc_common_view_lib_glsl, datatoc_common_globals_lib_glsl, datatoc_wireframe_frag_glsl, NULL}, .defs = (const char *[]){sh_cfg->def, custom_bias ? "#define CUSTOM_DEPTH_BIAS\n" : NULL, NULL}, }); } return sh_data->wireframe[custom_bias]; }
ワイヤーフレームの色をセットしている場所の特定
wire_color_get()
を見ると、colorWire
という変数が見つかりました。この変数にワイヤーフレームの色がセットされていそうです。
void wire_color_get(out vec3 rim_col, out vec3 wire_col) { [...] else if (is_selected && useColoring) { if (isTransform) { rim_col = colorTransform.rgb; } else if (is_active) { rim_col = colorActive.rgb; } else { rim_col = colorSelect.rgb; } wire_col = colorWire.rgb; } else { rim_col = colorWire.rgb; wire_col = colorBackground.rgb; } }
colorWire
をgrepしてみると、以下のuniform変数として定義されていることが分かりました。
source/blender/draw/intern/shaders/common_globals_lib.glsl
/* keep in sync with GlobalsUboStorage */
layout(std140) uniform globalsBlock
{
vec4 colorWire;
vec4 colorWireEdit;
vec4 colorActive;
vec4 colorSelect;
[...]
もう少し探索を進めると、uniform変数にセットしていそうなコードが見つかりました。
UI_GetThemeColor4fv(TH_WIRE, gb->colorWire);
にbreak pointをセットしてみます。
デバッガで確認すると、初回実行時には、ゼロ初期化されていて、DRW_globals_update(void)
の呼び出し後は、
gb->colorWire
に(0, 0, 0, 1)がセットされました。
source/blender/draw/intern/draw_common.c
void DRW_globals_update(void) { GlobalsUboStorage *gb = &G_draw.block; UI_GetThemeColor4fv(TH_WIRE, gb->colorWire); UI_GetThemeColor4fv(TH_WIRE_EDIT, gb->colorWireEdit); UI_GetThemeColor4fv(TH_ACTIVE, gb->colorActive); UI_GetThemeColor4fv(TH_SELECT, gb->colorSelect); [...]
コードの修正
colorWire
は、float[4]
でそれぞれの要素はRGBAに対応しているようです。
そこで、rgba = (1, 0, 0, 1)
、つまり赤をセットしてみます。
diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c index 132b5274517..db7501e6a94 100644 --- a/source/blender/draw/intern/draw_common.c +++ b/source/blender/draw/intern/draw_common.c @@ -53,7 +53,12 @@ void DRW_globals_update(void) { GlobalsUboStorage *gb = &G_draw.block; - UI_GetThemeColor4fv(TH_WIRE, gb->colorWire); + gb->colorWire[0] = 1.0; + gb->colorWire[1] = 0.0; + gb->colorWire[2] = 0.0; + gb->colorWire[3] = 1.0; + + //UI_GetThemeColor4fv(TH_WIRE, gb->colorWire); UI_GetThemeColor4fv(TH_WIRE_EDIT, gb->colorWireEdit); UI_GetThemeColor4fv(TH_ACTIVE, gb->colorActive); UI_GetThemeColor4fv(TH_SELECT, gb->colorSelect);
ビルドと実行結果
ビルドして実行し、ワイヤーフレームで表示すると無事ワイヤーフレームの色が赤くなりました。
関連情報
ワイヤーフレームの不透明度をUIから変更できるようにする修正
Blenderのはじめての不具合改修
はじめに
BlenderをXcodeでデバッグ実行した時にNull Pointer Exceptionが発生する不具合を発見しました。 軽微な不具合だったので、改修してパッチを送りました。その過程を簡単にメモに残しておきます。
使用したコード
master (af940c68cbed7e840d6ae58f2645ff12ed6abffb) 2.93.0を使用しました。
バグの詳細
環境変数BLENDER_SYSTEM_PYTHON
を未設定の状態でBlenderを実行すると、Null Pointer Exceptionが発生します。
こちらに詳細をまとめて、パッチを送りました。
https://developer.blender.org/D10494
git log
とgit blame
でバグが混入したコミットを特定しました。
パッチの作成
このページに書かれている、Arcanistをインストールしました。 https://wiki.blender.org/wiki/Tools/CodeReview
はじめて使用する際には、以下のコマンドを実行して、パッチの送付先のシステム認証を行う必要があります。
% arc install-certificate
以下のコマンドを実行するとコードのコミットとチケットの作成が行われます。
% arc diff
コミッターにレビューを依頼しました。
無事、修正が取り込まれました。 https://developer.blender.org/rB06212759bc7285a131c3ee811aec1ee240841c2c
commit 06212759bc7285a131c3ee811aec1ee240841c2c Author: Campbell Barton <ideasman42@gmail.com> Date: Mon Feb 22 21:20:48 2021 +1100 Fix missing NULL check on macOS when system-python isn't found Regression from cafd6b519c5f5c4b67d0dfe3d453cd4223b38716. D10494 by @ysano with edits.
Hello Blender Hack: bpy.app.ocio.supportedの値を変更してみる
はじめに
Blenderにごく簡単な修正をして、修正が反映されるのを確認する実験をしてみます。 修正自体は、何も面白くないですが、BlenderのHackingの第一歩としては意義があると思います。
使用したコード
master (af940c68cbed7e840d6ae58f2645ff12ed6abffb) 2.93.0を使用しました。
修正前の挙動の確認
Blenderの組み込みPythonシェルで以下を評価するとTrue
が返りました。
>>> bpy.app.ocio.supported True
挙動に対応するコード
source/blender/python/intern/bpy_app_ocio.c
にbpy.app.ocio
をセットするコードが見つかりました。
ローカル変数pos
をインクリメントしながら、プロパティを順番にセットしているようです。
SetObjItem(PyBool_FromLong(1));
でbpy.app.ocio.supported
がTrue
を返すように実装していそうです。
static PyObject *make_ocio_info(void) { PyObject *ocio_info; int pos = 0; #ifdef WITH_OCIO int curversion; #endif ocio_info = PyStructSequence_New(&BlenderAppOCIOType); if (ocio_info == NULL) { return NULL; } #ifndef WITH_OCIO # define SetStrItem(str) PyStructSequence_SET_ITEM(ocio_info, pos++, PyUnicode_FromString(str)) #endif #define SetObjItem(obj) PyStructSequence_SET_ITEM(ocio_info, pos++, obj) #ifdef WITH_OCIO curversion = OCIO_getVersionHex(); SetObjItem(PyBool_FromLong(1)); SetObjItem( PyC_Tuple_Pack_I32(curversion >> 24, (curversion >> 16) % 256, (curversion >> 8) % 256)); SetObjItem(PyUnicode_FromFormat( "%2d, %2d, %2d", curversion >> 24, (curversion >> 16) % 256, (curversion >> 8) % 256)); #else SetObjItem(PyBool_FromLong(0)); SetObjItem(PyC_Tuple_Pack_I32(0, 0, 0)); SetStrItem("Unknown"); #endif if (PyErr_Occurred()) { Py_CLEAR(ocio_info); return NULL; } #undef SetStrItem #undef SetObjItem return ocio_info; }
コードの修正
そこで以下のように修正します。0
をセットすることでFalse
を返すようになるのではと考えました。
% git diff diff --git a/source/blender/python/intern/bpy_app_ocio.c b/source/blender/python/intern/bpy_app_ocio.c index 3a36e90018f..125f03e2a52 100644 --- a/source/blender/python/intern/bpy_app_ocio.c +++ b/source/blender/python/intern/bpy_app_ocio.c @@ -70,7 +70,7 @@ static PyObject *make_ocio_info(void) #ifdef WITH_OCIO curversion = OCIO_getVersionHex(); - SetObjItem(PyBool_FromLong(1)); + SetObjItem(PyBool_FromLong(0)); SetObjItem( PyC_Tuple_Pack_I32(curversion >> 24, (curversion >> 16) % 256, (curversion >> 8) % 256)); SetObjItem(PyUnicode_FromFormat(
修正結果の確認
修正後、Xcodeでビルドと実行します。
Blender組み込みのPythonシェルで確認すると、予想通りbpy.app.ocio.supported
がFalse
を返すようになりました。
macOS: XcodeでBlenderの開発環境を構築する
はじめに
今回はBlenderをXcodeでビルドしてデバッグ実行するまでの工程を記録に残します。 公式マニュアルで不足していた部分を補足します。
手順
公式マニュアルを参考にしました。 https://wiki.blender.org/wiki/Building_Blender/Mac
Xcodeのインストール
App Storeから最新のXcodeをインストールしました。 時間がかかりますがしばらく放置します。
Homebrewのインストール
cmakeとsvnのインストール
% brew install cmake svn
ソースコードと依存外部ライブラリの取得
make update
のタイミングで外部依存ライブラリが取得されます。
% mkdir ~/blender-git % cd ~/blender-git % git clone https://git.blender.org/blender.git % cd blender % make update
Xcodeのプロジェクトファイルの生成
ビルドしたBlenderの配置先を作成し、ビルド時にそこに配置されるようにCMAKE_INSTALL_PREFIXを指定します。 cmakeが成功すると、build_xcode/Blender.xcodeprojが生成されます。
CMAKE_INSTALL_PREFIXを指定しないと、書き込み権限が無いため、ビルドに失敗しました。
% mkdir /Users/yoshinori_sano/build % cd ~/blender-git/blender % cmake . -B ../build_xcode/ -G "Xcode" -DCMAKE_INSTALL_PREFIX=/Users/yoshinori_sano/build
Xcodeの設定
Blender.xcodeprojを開きます。
Automatically Create Schemesを選択します。
Active Schemeをinstallに設定します。
Product->Scheme->Edit Schemeを選択し、RunのexecutableにBlender.appを選択します。 Environmental Variablesに以下を設定します。 これらの環境変数をセットしないと、XcodeからBlenderを起動できません。
- BLENDER_SYSTEM_PYTHON: /Users/yoshinori_sano/build/Blender.app/Contents/Resources/2.93/python
- BLENDER_SYSTEM_DATAFILES: /Users/yoshinori_sano/build/Blender.app/Contents/Resources/2.93/datafiles
- BLENDER_SYSTEM_SCRIPTS: /Users/yoshinori_sano/build/Blender.app/Contents/Resources/2.93/scripts
Choseをクリックして設定を保存します。
デバッグ実行
source/creator/creator.c
にmain()
があるので、適当な場所にbreak pointをセットします。
Runボタンをクリックするとビルドが開始されます。 ビルドが正常に完了したら、Debug版のBlenderが起動します。
設定したbreak pointで実行が停止します。
実行を続行すると、BlenderのUIが表示されます。