こんにちは、JS2IIUです。
今回は、StreamlitとPlotlyを使って、Blenderで作成した3Dモデルをブラウザ上で自由に視点を変えながら表示できるWebアプリケーションを作成する方法をご紹介します。今回もよろしくお願いします。
1. はじめに
3Dモデルをウェブ上で共有・表示したいニーズは多くありますが、専用のビューワーソフトをインストールする必要があったり、操作が複雑だったりすることが多いものです。今回紹介するアプリケーションでは、Streamlitの簡単さとPlotlyの強力な3D表示機能を組み合わせることで、ブラウザだけで3Dモデルを表示・操作できるようにします。
2. 必要な環境とライブラリ
まずは必要なライブラリをインストールしましょう:
Python
pip install streamlit numpy plotly trimesh各ライブラリの役割:
- Streamlit: Webアプリケーションのフレームワーク
- NumPy: 数値計算ライブラリ
- Plotly: インタラクティブな3D表示
- Trimesh: 3Dメッシュデータの読み込みと処理
3. Blenderからのデータエクスポート
Blenderから3Dモデルをエクスポートする手順は以下の通りです:
- Blenderで対象のモデルを選択
- メニューから「ファイル」→「エクスポート」→「Wavefront (.obj)」を選択
- エクスポート設定で以下を確認:
- Selection Only: チェックを入れる(選択したモデルのみエクスポート)
- Transform: Apply Modifiers にチェックを入れる
- Geometry: Triangulate Faces にチェックを入れる
- エクスポート先を選択して「OBJをエクスポート」をクリック
注意点:
- テクスチャや材質情報は現在のビューワーでは表示されません
- モデルが複雑すぎると表示が重くなる可能性があります
- できるだけ三角形ポリゴンでエクスポートすることをお勧めします
4. アプリケーションの実装
コードの全体を示します。
Python
import streamlit as st
import numpy as np
import plotly.graph_objects as go
import trimesh
import os
def load_obj_file(uploaded_file):
"""
アップロードされたOBJファイルをロードする関数
"""
# 一時ファイルとして保存
with open("temp.obj", "wb") as f:
f.write(uploaded_file.getbuffer())
# trimeshでメッシュを読み込む
mesh = trimesh.load("temp.obj")
# 一時ファイルを削除
os.remove("temp.obj")
return mesh
def main():
# ページ設定
st.set_page_config(
page_title="3D Model Viewer",
layout="wide"
)
# タイトルと説明
st.title("3Dモデルビューワー")
st.write("Blenderからエクスポートした3DモデルをWeb上で表示できます。")
# ファイルアップローダーを追加
uploaded_file = st.file_uploader(
"OBJファイルをアップロード",
type=['obj'],
help="Blenderからエクスポートした.objファイルをアップロードしてください。"
)
if uploaded_file is not None:
try:
# 2カラムレイアウトを作成
col1, col2 = st.columns([3, 1])
with col2:
st.header("表示設定")
# プロットのスタイル設定
opacity = st.slider(
"不透明度",
min_value=0.0,
max_value=1.0,
value=1.0,
step=0.1
)
wireframe = st.checkbox("ワイヤーフレーム表示", False)
color_scheme = st.selectbox(
"カラースキーム",
["Viridis", "Plasma", "Inferno", "Magma"]
)
st.markdown("""
### 操作方法
- マウスドラッグ: 回転
- マウスホイール: ズーム
- Shift+ドラッグ: 平行移動
- ダブルクリック: ビューをリセット
""")
with col1:
# メッシュの読み込み
mesh = load_obj_file(uploaded_file)
# メッシュデータの取得
vertices = mesh.vertices
faces = mesh.faces
# 3Dプロットの作成
fig = go.Figure()
# メッシュの表示
fig.add_trace(go.Mesh3d(
x=vertices[:, 0],
y=vertices[:, 1],
z=vertices[:, 2],
i=faces[:, 0],
j=faces[:, 1],
k=faces[:, 2],
opacity=opacity,
colorscale=color_scheme.lower(),
intensity=vertices[:, 2], # Z座標を基にした色付け
showscale=True
))
# ワイヤーフレーム表示
if wireframe:
for face in faces:
vertices_face = vertices[face]
vertices_face = np.vstack([vertices_face, vertices_face[0]])
fig.add_trace(go.Scatter3d(
x=vertices_face[:, 0],
y=vertices_face[:, 1],
z=vertices_face[:, 2],
mode='lines',
line=dict(color='black', width=1),
showlegend=False
))
# レイアウトの設定
fig.update_layout(
scene=dict(
xaxis_title="X軸",
yaxis_title="Y軸",
zaxis_title="Z軸",
camera=dict(
up=dict(x=0, y=0, z=1),
center=dict(x=0, y=0, z=0),
eye=dict(x=1.5, y=1.5, z=1.5)
),
aspectmode='data' # 実際のスケールを維持
),
margin=dict(l=0, r=0, t=0, b=0),
height=700 # プロットの高さを指定
)
# Streamlitでプロットを表示
st.plotly_chart(fig, use_container_width=True)
# モデル情報の表示
st.write("### モデル情報")
st.write(f"頂点数: {len(vertices):,}")
st.write(f"面の数: {len(faces):,}")
except Exception as e:
st.error(f"エラーが発生しました: {str(e)}")
st.error("ファイルの形式が正しくないか、データが破損している可能性があります。")
else:
st.info("OBJファイルをアップロードしてください。")
# 使い方の説明
st.markdown("""
### 使い方
1. Blenderでモデルを選択し、File > Export > Wavefront (.obj)を選択
2. エクスポート設定で以下を確認:
- Selection Only: チェックを入れる
- Transform: Apply Modifiers にチェック
- Geometry: Triangulate Faces にチェック
3. エクスポートしたOBJファイルをこのページにアップロード
""")
if __name__ == "__main__":
main()アプリケーションのコアとなる機能を見ていきましょう。
主要な機能:
- OBJファイルのアップロードとロード
- 3Dメッシュの表示
- 表示設定の調整(不透明度、ワイヤーフレーム表示など)
- インタラクティブな視点操作
5. コードの詳細解説
OBJファイルの読み込み
Python
def load_obj_file(uploaded_file):
with open("temp.obj", "wb") as f:
f.write(uploaded_file.getbuffer())
mesh = trimesh.load("temp.obj")
os.remove("temp.obj")
return meshこのコードでは:
- アップロードされたファイルを一時的に保存
- trimeshを使用してメッシュデータを読み込み
- 一時ファイルを削除して後処理を整理
3Dビューワーのコア部分
Python
fig.add_trace(go.Mesh3d(
x=vertices[:, 0],
y=vertices[:, 1],
z=vertices[:, 2],
i=faces[:, 0],
j=faces[:, 1],
k=faces[:, 2],
opacity=opacity,
colorscale=color_scheme.lower(),
intensity=vertices[:, 2],
showscale=True
))この部分では:
- vertices(頂点データ)とfaces(面データ)を使用してメッシュを構築
- opacity(不透明度)とcolorscale(カラースキーム)でビジュアルをカスタマイズ
- intensityパラメータでZ座標に基づいた色付けを実現
ワイヤーフレーム表示の実装
Python
if wireframe:
for face in faces:
vertices_face = vertices[face]
vertices_face = np.vstack([vertices_face, vertices_face[0]])
fig.add_trace(go.Scatter3d(
x=vertices_face[:, 0],
y=vertices_face[:, 1],
z=vertices_face[:, 2],
mode='lines',
line=dict(color='black', width=1),
showlegend=False
))このコードでは:
- 各面の輪郭を線で描画
- 面の頂点を結んでワイヤーフレームを形成
- 最初の頂点に戻って閉じた形状を作成
6. カスタマイズのヒント
アプリケーションをさらに発展させるためのいくつかのアイデア:
- 表示機能の拡張
- テクスチャのサポート追加
- 複数のライティングオプション
- 断面表示機能
- ユーザビリティの向上
- モデルの自動スケーリング
- 視点のプリセット
- スクリーンショット機能
- パフォーマンスの最適化
- メッシュの簡略化オプション
- 大規模モデルの段階的読み込み
- WebGLベースのレンダリングへの移行
7. まとめ
このアプリケーションを使用することで、Blenderで作成した3Dモデルを簡単にWeb上で共有・表示することができます。Streamlitの直感的なUIとPlotlyの強力な3D表示機能を組み合わせることで、専門的な知識がなくても3Dビューワーを作成・カスタマイズすることが可能です。
コードはGitHubなどで公開して、コミュニティと共有することをお勧めします。多くの人がこのベースから独自の機能を追加し、より便利なツールに発展させていくことを期待しています。
参考リンク
以上で解説を終わります。質問やフィードバックがありましたら、コメント欄でお気軽にご連絡ください!

