在Blender的script裡使用FileBrowser選取檔案
前言
在上一篇
初探Blender的script中,基本的使用了Blender的Script,因應日後要開發匯入/匯出3D模組的外掛,就來研究怎麼在Script裡使用FileBrowser選取檔案,在此做個紀錄。
內容
在開始研究如何使用FileBrowser時,發現找不太到範例,在搜尋一陣子後才在
Use Blender's file browser via python, without a UI panel裡發現原來Blender有自帶範例,開啟了方式如下
|
開啟範例 |
在開啟範例後,會看到以下的程式碼
import bpy
def write_some_data(context, filepath, use_some_setting):
print("running write_some_data...")
f = open(filepath, 'w', encoding='utf-8')
f.write("Hello World %s" % use_some_setting)
f.close()
return {'FINISHED'}
# ExportHelper is a helper class, defines filename and
# invoke() function which calls the file selector.
from bpy_extras.io_utils import ExportHelper
from bpy.props import StringProperty, BoolProperty, EnumProperty
from bpy.types import Operator
class ExportSomeData(Operator, ExportHelper):
"""This appears in the tooltip of the operator and in the generated docs"""
bl_idname = "export_test.some_data" # important since its how bpy.ops.import_test.some_data is constructed
bl_label = "Export Some Data"
# ExportHelper mixin class uses this
filename_ext = ".txt"
filter_glob = StringProperty(
default="*.txt",
options={'HIDDEN'},
maxlen=255, # Max internal buffer length, longer would be clamped.
)
# List of operator properties, the attributes will be assigned
# to the class instance from the operator settings before calling.
use_setting = BoolProperty(
name="Example Boolean",
description="Example Tooltip",
default=True,
)
type = EnumProperty(
name="Example Enum",
description="Choose between two items",
items=(('OPT_A', "First Option", "Description one"),
('OPT_B', "Second Option", "Description two")),
default='OPT_A',
)
def execute(self, context):
return write_some_data(context, self.filepath, self.use_setting)
# Only needed if you want to add into a dynamic menu
def menu_func_export(self, context):
self.layout.operator(ExportSomeData.bl_idname, text="Text Export Operator")
def register():
bpy.utils.register_class(ExportSomeData)
bpy.types.INFO_MT_file_export.append(menu_func_export)
def unregister():
bpy.utils.unregister_class(ExportSomeData)
bpy.types.INFO_MT_file_export.remove(menu_func_export)
if __name__ == "__main__":
register()
# test call
bpy.ops.export_test.some_data('INVOKE_DEFAULT')
在第一次看時實在是看不太懂,所以我找了另一個教學
Blender 3D: Noob to Pro/Advanced Tutorials/Blender Scripting/A User Interface For Your Addon,這個教學裡會教你用Script寫Operator,並且製作UI來啟動Operator,具體的程式碼如下
import math
import bpy
import mathutils
class TetrahedronMakerPanel(bpy.types.Panel):
bl_space_type = "VIEW_3D"
bl_region_type = "TOOLS"
bl_context = "objectmode"
bl_category = "Create"
bl_label = "Add Tetrahedron"
def draw(self, context):
TheCol = self.layout.column(align=True)
TheCol.operator("mesh.make_tetrahedron", text="Add Tetrahedron")
#end draw
#end TetrahedronMakerPanel
class MakeTetrahedron(bpy.types.Operator):
bl_idname = "mesh.make_tetrahedron"
bl_label = "Add Tetrahedron"
bl_options = {"UNDO"}
def invoke(self, context, event):
Vertices = \
[
mathutils.Vector((0, -1 / math.sqrt(3),0)),
mathutils.Vector((0.5, 1 / (2 * math.sqrt(3)), 0)),
mathutils.Vector((-0.5, 1 / (2 * math.sqrt(3)), 0)),
mathutils.Vector((0, 0, math.sqrt(2 / 3))),
]
NewMesh = bpy.data.meshes.new("Tetrahedron")
NewMesh.from_pydata \
(
Vertices,
[],
[[0, 1, 2], [0, 1, 3], [1, 2, 3], [2, 0, 3]]
)
NewMesh.update()
NewObj = bpy.data.objects.new("Tetrahedron", NewMesh)
context.scene.objects.link(NewObj)
return {"FINISHED"}
#end invoke
#end MakeTetrahedron
bpy.utils.register_class(MakeTetrahedron)
bpy.utils.register_class(TetrahedronMakerPanel)
可以看到是Panel與Operator,TetrahedronMakerPanel是UI的部分,MakeTetrahedron則是Operator,接著最後透過register來註冊後使用。TetrahedronMakerPanel透過繼承Panel後再修改相關Property,接著透過Draw來新增一個按鍵來驅動Operator。bl_space_type是Editor的Type,在這個範例是註冊在3DView的Editor,bl_context代表的是在ObjectMode才會出現,bl_category 則是標籤的名稱,如果是不存在的標籤會自動新增,bl_label則是Panel的顯示名稱。接著是 MakeTetrahedron,透過繼承Operator後,修改相關的Property,接著透過invoke來執行程式碼。bl_idname是Operator要註冊的名稱,記住不要大寫! bl_label則是Operator的註解要顯示的字串。從這兩個例子可以看出Blender寫外掛時的模式是透過繼承後修改相關Property並重仔相關Method後,再透過register後使用。
回到輸出檔案的範例, 可以看到ExportSomeData繼承Panel與ExportHelper,透過修改相關Property後,重載execute(),但這裡的重載Method的執行時機不太一樣,這個Method會在File browser裡的"Export Some Data"按下時才執行,如果是按下"Cancel"的話就不會被執行。在execute()裡可以在self.filepath這個Property取得儲存檔案的位置。write_some_data()這裡就是Python的基本開檔寫資料。在最後可以看到bpy.ops.export_test.some_data('INVOKE_DEFAULT')這行,這行是直接執行Operator的做法,不用透過UI驅動,可以學起來。
後記
雖然第一次看到Blender的範例看不懂,但在經過學習後發現這個做法的程式碼相當簡潔,可真是學習了,本篇文章只看了export的範例,import的範例就不再寫了,因為作法是相像的。
參考資料
Use Blender's file browser via python, without a UI panel
Blender 3D: Noob to Pro/Advanced Tutorials/Blender Scripting/A User Interface For Your Addon