BlenderへPLATEAUのモデルを2時間40分かけてインポートした話
昨日は、はじめてBlender pythonを使用してimportした4~5000個ほどのオブジェクトを7つのオブジェクトにまとめ、マテリアルのセット、UV unwrapといった作業を自動化した。
いつかfbxのimportも自動化したいな思っていたが暇だったのでやってみた。
1.ソース
pythonの作法とか知らないので自分で分かればいいやレベルの汚ソース。target_dir
のFPXAssets
は綴りを間違えているがあえて放置している。
import glob import bpy import math target_dir="D:\\FPXAssets\\13100_tokyo23-ku_2020_fbx_3_op\\bldg\\lod1" search_key="533925" path_list=glob.glob(target_dir + '\\' + search_key + '*') # コレクションの検索用関数 def recurLayerCollection(layerColl, collName): found = None if (layerColl.name == collName): return layerColl for layer in layerColl.children: found = recurLayerCollection(layer, collName) if found: return found # fbxデータ内のオブジェクトをランダムで7個にする関数 def randomJoinObjects(): divNum = [0.14, 0.17, 0.2, 0.25, 0.33, 0.5, 1] sd = 1 for div in divNum: bpy.ops.object.select_random(ratio=div, seed=sd) # Join先のオブジェクトを有効化 target = bpy.context.selected_objects[0] bpy.context.view_layer.objects.active = target bpy.ops.object.join() # UV unwrap処理 if(target.data.uv_layers=='None'): bpy.ops.mesh.uv_texture_add() bpy.ops.object.editmode_toggle() bpy.ops.uv.smart_project(angle_limit=math.radians(66), island_margin=0, area_weight=0, correct_aspect=True, scale_to_bounds=False) bpy.ops.object.editmode_toggle() # マテリアルのセット if target.data.materials: target.data.materials[0] = bpy.data.materials[sd] else: target.data.materials.append(bpy.data.materials[sd]) # hideしてワンセット終わり for o in bpy.context.selected_objects: o.hide_set(True) # ランダムシード値の更新 sd += 1 for f in path_list: # 新しいコレクションの名前を作成 i=f.find(search_key) new_col_name=f[(i+len(search_key)):(i+len(search_key)+2)] # コレクションを作成 new_col = bpy.data.collections.new(new_col_name) bpy.context.scene.collection.children.link(new_col) # 作成したコレクションのアクティブ化 layer_collection=bpy.context.view_layer.layer_collection layer_col = recurLayerCollection(layer_collection, new_col.name) bpy.context.view_layer.active_layer_collection = layer_col # FBXファイルのインポート bpy.ops.import_scene.fbx(filepath=f) # ランダムに7つのオブジェクトへマージする処理 # import後はすべて選択されているので選択を解除しておく bpy.ops.object.select_all(action='DESELECT') randomJoinObjects()
2. ソースのメモ
モデルの加工部分は前の記事で書いたので、今回はそれ以外の部分について気になった点をメモしておく。
- Collectionをアクティブにするのがめんどい
すぐ思いつく簡単な方法が通らなかったので検索。↑のdef recurLayerCollection(layerColl, collName)
は以下を参考にした。
https://blender.stackexchange.com/
Change active collection - UV unwrapのパラメータがラジアン
画面上はオイラーアングル?っぽいけどAPIではfloat0~1.xxまでとか書いている。ラジアンらしいのでmath.radians()
を使った。 - オブジェクトの選択解除どうする?
bpy.ops.object.select_all(action='DESELECT')
テストした インポートからの加工が一瞬で終わって少し感動したが、これで楽できると思ったら大間違いだった。
3.実際に使ってみた
PLATEAUのLOD1の建物をエリア単位でインポートしてみる。昨日手作業でインポートした大田区エリアは30ファイルあり、およそ1時間程度を要した。今回選択した目黒・品川エリアはファイル数は96と多いが自動化したのだからと期待は大きかった。
スクリプト実行でBlenderは即応答なしの状態へ入り不安に襲われる。タスクマネージャを起動してCPU,RAMの使用状況が変動していることからフリーズでは無いと判断。アニメを見たりして気を紛らわす
1時間後コンビニにでかけて帰ってきてもまだ応答がない。仕方がないのでパソコンの前でヨガを始める。呼吸に集中していると、時折PCのファンの回転数が上昇してBlenderの息吹を感じた。まだフリーズしていない。
ヨガが終わって買ってきたポテチを食べようとした頃にようやく完了した。開始からおよそ2時間40分、信じてよかった。
4.まとめ
今回は成功したからいいものの、失敗していたら相当落ち込む。一度にインポートするファイル数を減らすかコンソールにログを出力して正常に動作していることを確認できる仕組みを取り入れることができるのならやってみたい。