在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 panelBlender 3D: Noob to Pro/Advanced Tutorials/Blender Scripting/A User Interface For Your Addon
沒有留言:
張貼留言