# ##### BEGIN GPL LICENSE BLOCK ##### # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # ##### END GPL LICENSE BLOCK ##### # bl_info = { "name": "Pie Menus Official", "author": "Antony Riakiotakis", "version": (1, 0, 0), "blender": (2, 71, 4), "description": "Enable official pie Menus in blender", "category": "User Interface", } import bpy from bpy.types import Menu, Operator from bpy.props import EnumProperty # " # "記号がコメントの記号になるので、 # 機能の説明を書き残しておきたいときや作成途中の文字列は" # "を行の最初に付けるとその行だけ無効化されるので便利。 # =============================================================== # =============================================================== # ここから各項目の設定 # =============================================================== # =============================================================== # オブジェクトモード切り替え class VIEW3D_PIE_object_mode(Menu): bl_label = "Mode" def draw(self, context): layout = self.layout pie = layout.menu_pie() # =============================================================== # =============================================================== # 視点切り替え class VIEW3D_PIE_view(Menu): bl_label = "select_mode" def draw(self, context): layout = self.layout pie = layout.menu_pie() pie.operator_enum("VIEW3D_OT_viewnumpad", "type") # =============================================================== # =============================================================== # シェード切り替え class VIEW3D_PIE_shade(Menu): bl_label = "Shade" def draw(self, context): layout = self.layout pie = layout.menu_pie() pie.prop(context.space_data, "viewport_shade", expand=True) if context.active_object: if(context.mode == 'EDIT_MESH'): pie.operator("MESH_OT_faces_shade_smooth") pie.operator("MESH_OT_faces_shade_flat") else: pie.operator("OBJECT_OT_shade_smooth") pie.operator("OBJECT_OT_shade_flat") # =============================================================== # =============================================================== # マニピュレーター切り替え class VIEW3D_manipulator_set(Operator): bl_label = "Set Manipulator" bl_idname = "view3d.manipulator_set" type = EnumProperty( name="Type", items=(('TRANSLATE', "Translate", "Use the manipulator for movement transformations"), ('ROTATE', "Rotate", "Use the manipulator for rotation transformations"), ('SCALE', "Scale", "Use the manipulator for scale transformations"), ), ) def execute(self, context): #show manipulator if user selects an option context.space_data.show_manipulator = True context.space_data.transform_manipulators = {self.type} return {'FINISHED'} # =============================================================== # =============================================================== # マニピュレーター切り替え class VIEW3D_PIE_manipulator(Menu): bl_label = "Manipulator" def draw(self, context): layout = self.layout pie = layout.menu_pie() pie.operator("view3d.manipulator_set", icon='MAN_TRANS', text="Translate").type = 'TRANSLATE' pie.operator("view3d.manipulator_set", icon='MAN_ROT', text="Rotate").type = 'ROTATE' pie.operator("view3d.manipulator_set", icon='MAN_SCALE', text="Scale").type = 'SCALE' pie.prop(context.space_data, "show_manipulator") # =============================================================== # =============================================================== # ピボット切り替え class VIEW3D_PIE_pivot(Menu): bl_label = "Pivot" def draw(self, context): layout = self.layout pie = layout.menu_pie() pie.prop(context.space_data, "pivot_point", expand=True) if context.active_object.mode == 'OBJECT': pie.prop(context.space_data, "use_pivot_point_align", text="Center Points") #ここまで、デフォルトで用意されている設定 # =============================================================== # =============================================================== # ここから自分で追加した設定 # =============================================================== # =============================================================== # 削除 (自分で追加したパイメニュー) class VIEW3D_PIE_DELxx(Menu): bl_label = "DELETE" def draw(self, context): layout = self.layout toolsettings = context.tool_settings pie = layout.menu_pie() pie.operator("mesh.delete", icon='VERTEXSEL', text="V").type='VERT' pie.operator("mesh.delete", icon='EDGESEL', text="E").type='EDGE' pie.operator("mesh.delete", icon='FACESEL', text="F").type='FACE' pie.operator("mesh.dissolve_faces", icon='FACESEL', text="F_dissolve") pie.operator("mesh.dissolve_verts", icon='VERTEXSEL', text="V_dissolve") pie.operator("mesh.dissolve_edges", icon='EDGESEL', text="E_dissolve") # =============================================================== # =============================================================== # メッシュ選択切り替え (自分で追加したパイメニュー) class VIEW3D_PIE_MESH(Menu): bl_label = "MESH" def draw(self, context): layout = self.layout toolsettings = context.tool_settings pie = layout.menu_pie() pie.operator_enum("mesh.select_mode", "type") #ここから空のパイメニュー。 # 空白の設定を3つ置いておくので、自分が欲しい設定を追加したい時に使ってください。 # =============================================================== # =============================================================== # 空のパイメニュー01 サンプル class VIEW3D_PIE_A01(Menu):# ←Blenderの入力(input)設定上で見える名前 bl_label = "A01"# ←パイメニューを起動させた時に中央に表示される名前。日本語OK def draw(self, context): layout = self.layout toolsettings = context.tool_settings pie = layout.menu_pie() pie.operator("mesh.primitive_cube_add", text="Cube", icon='MESH_CUBE')# ←キューブを追加 pie.operator("transform.resize", text="Scale")# ←拡大・収縮 pie.operator("object.modifier_add", text="Mirror", icon='MOD_MIRROR').type='MIRROR'# ←モディファイアのミラーを適応 # ↑ ここに設定させたい動作を貼り付ける。今は例としてメッシュ選択切り替えの設定が書かれている。 #■やり方 #まずはアドオンの場所を探す。 #(Macの場合) #「⌘ + Shift + G」で「フォルダへ移動…」のダイアログを出す #そこに下記のパスをコピペしてアドオンの場所へ移動する。 #/Applications/Blender/blender.app/Contents/Resources/2.72/scripts/addons/ui_pie_menus_official.py# #「ui_pie_menus_official.py」を複製してバックアップをとっておく #このテキストをアドオンフォルダに追加して上書きする。 #「ui_pie_menus_official.py」を開く。見れるものならなんでもよいが、色分けできるテキストエディターで開けば文字が色分けされて見やすいだろう。 # # #▼設定したい動作の文字列を取得する #Blenderの方は「テキストエディタ」ウィンドウを増やしておく。 #BlenderのT/Nプロパティやヘッターなどにある、設定させたい動作を右クリックし、でてきたメニューの中の「ソースの編集」をクリックする。 #すると、テキストエディタの方に大元のソースが出てくる。 # 例えば「移動」のソースを見た場合はこのようになっている。 # col.operator("transform.translate") # この現在カーソルが置かれている行をコピーする。 #この時、絶対に編集したりしないこと。やったことはないが、変にいじるとバグると思われる。 #コピーした行を上の場所に貼り付ける。 #この時、インデントがきっちり揃ってなかったり、無駄な文字が入っているとエラーが出るので、本当にコピーした行を丸ごと貼り付けることをおすすめする。 # 次に、貼り付けたテキストをパイメニューで使えるようにするため、「col」部分を、「pie」に変更する。 # col.operator("transform.translate") # ↓ # pie.operator("transform.translate") # #▼「ソースを編集」がない場合 #項目がメニューになっていて複数項目ある設定によくある。 #その場合は「Python PLI プリファレンス」を方をクリックしする。 #クリックすると、英語だがその動作のPythonについて詳細に書かれているサイトに飛ぶので、それらしきものをコピーし、下のような感じに当てはめる。 #下の例はモディファイアのミラーをパイメニューの形式に当てはめた。 # # モディファイアを追加する 追加するモディファイア # ↓ ↓ # pie.operator("object.modifier_add").type='MIRROR' # # #▼パイメニューを修飾する #パイメニューにアイコンやタイトルを付けることができる。 # 表示する名前 アイコン # ↓ ↓ # pie.operator("object.modifier_add", text="Mirror", icon='MOD_MIRROR').type='MIRROR' # # # #そして、上書き保存したらBlenderに戻る。 #ユーザー設定 →アドオン →「pie」と検索 →出てきた「ui_pie_menus_official」のチェックを外して、またチェックを付ける。なにもエラーメッセージがでなければ正常に読み込まれている。 #エラーが出た場合は、もう一度目の皿のようにして間違いがないか確認する。できるかぎり正常に読み込みができている項目を、コピペして改変するのが確実で堅実だ。 # #最後に、実際に動作を確認してみる。 #ユーザー設定 → 入力 の検索窓に、「pie」と入力し、検索方法は「名前」で検索する。 #設定されたパイメニューの一覧が出てくる。 #しかし、不便なことに全て名前が「パイメニュー呼び出し」となっていてどれがどれだか識別しづらい。 #用意した空のパイメニューのショートカットを変更していないのであれば、全て「A」に設定されているので、それで見分けるとよい。 #項目を開いてみると、右下の方に実際に付けた名前が見える。 #好きにショートカットを変更したり、不要な項目のチェックを外したりして、ショートカットが重複しないようにすること。 #ショートカットが設定できたら、左上の「ユーザー設定の保存」で設定を保存しておくこと。 # # # # # ▼パイメニューの機能の設定 # ユーザー設定 → インターフェーイス の右下にパイメニューの設定項目がある。 # 使いやすいよう調節するとよい。なるべく早く動作させたい場合は、どの値も小さくするのがおすすめ。 # 私は、順番に0 、0 、25 、20 のように設定している。 # ・アニメーションタイムアウト ……起動してから項目が出てくるスピード。 # ・リセンタータイムアウト ……よくわからん。 # ・半径 ……項目の広さ。パイメニューを大きく表示させたくない場合は小さくする。 # ・しきい値 ……円の大きさ。円までマウスカーソルを持って行くと実行されるので、その距離を変更できる。 # =============================================================== # =============================================================== # 空のパイメニュー02 class VIEW3D_PIE_A02(Menu): bl_label = "A01" def draw(self, context): layout = self.layout toolsettings = context.tool_settings pie = layout.menu_pie() pie.operator_enum("mesh.select_mode", "type") # =============================================================== # =============================================================== # 空のパイメニュー03 class VIEW3D_PIE_A03(Menu): bl_label = "A01" def draw(self, context): layout = self.layout toolsettings = context.tool_settings pie = layout.menu_pie() pie.operator_enum("mesh.select_mode", "type") #=============================================================== addon_keymaps = [] #===============================================================〜 # ここまで、各項目の設定 # =============================================================== # =============================================================== # ここからなんか知らんけどやらなきゃいけない設定諸々 # =============================================================== # =============================================================== def register(): bpy.utils.register_class(VIEW3D_manipulator_set) #register menus bpy.utils.register_class(VIEW3D_PIE_object_mode) bpy.utils.register_class(VIEW3D_PIE_view) bpy.utils.register_class(VIEW3D_PIE_shade) bpy.utils.register_class(VIEW3D_PIE_manipulator) bpy.utils.register_class(VIEW3D_PIE_pivot) bpy.utils.register_class(VIEW3D_PIE_DELxx) #←削除 bpy.utils.register_class(VIEW3D_PIE_MESH) # ←メッシュ選択切り替え bpy.utils.register_class(VIEW3D_PIE_A01) bpy.utils.register_class(VIEW3D_PIE_A02) bpy.utils.register_class(VIEW3D_PIE_A03) # =============================================================== # =============================================================== #ショートカット設定 wm = bpy.context.window_manager if wm.keyconfigs.addon: km = wm.keyconfigs.addon.keymaps.new(name='Object Non-modal') kmi = km.keymap_items.new('wm.call_menu_pie', 'TAB', 'PRESS') kmi.properties.name = 'VIEW3D_PIE_object_mode' kmi = km.keymap_items.new('wm.call_menu_pie', 'Z', 'PRESS') kmi.properties.name = 'VIEW3D_PIE_shade' kmi = km.keymap_items.new('wm.call_menu_pie', 'Q', 'PRESS') kmi.properties.name = 'VIEW3D_PIE_view' kmi = km.keymap_items.new('wm.call_menu_pie', 'SPACE', 'PRESS', ctrl=True) kmi.properties.name = 'VIEW3D_PIE_manipulator' kmi = km.keymap_items.new('wm.call_menu_pie', 'PERIOD', 'PRESS') kmi.properties.name = 'VIEW3D_PIE_pivot' kmi = km.keymap_items.new('wm.call_menu_pie', 'X', 'PRESS', alt=True) #←削除のショートカット kmi.properties.name = 'VIEW3D_PIE_DELxx' #←削除 kmi = km.keymap_items.new('wm.call_menu_pie', 'X', 'PRESS') #←メッシュ選択切り替えのショートカット kmi.properties.name = 'VIEW3D_PIE_MESH' #←メッシュ選択切り替え kmi = km.keymap_items.new('wm.call_menu_pie', 'Z', 'PRESS') kmi.properties.name = 'VIEW3D_PIE_A01' kmi = km.keymap_items.new('wm.call_menu_pie', 'Z', 'PRESS') kmi.properties.name = 'VIEW3D_PIE_A02' kmi = km.keymap_items.new('wm.call_menu_pie', 'Z', 'PRESS') kmi.properties.name = 'VIEW3D_PIE_A03' # =============================================================== addon_keymaps.append(km) # =============================================================== # =============================================================== # =============================================================== def unregister(): bpy.utils.unregister_class(VIEW3D_manipulator_set) bpy.utils.unregister_class(VIEW3D_PIE_object_mode) bpy.utils.unregister_class(VIEW3D_PIE_view) bpy.utils.unregister_class(VIEW3D_PIE_shade) bpy.utils.unregister_class(VIEW3D_PIE_manipulator) bpy.utils.unregister_class(VIEW3D_PIE_pivot) bpy.utils.unregister_class(VIEW3D_PIE_DELxx) # ←削除 bpy.utils.unregister_class(VIEW3D_PIE_MESH) # ←メッシュ選択切り替え bpy.utils.unregister_class(VIEW3D_PIE_A01) bpy.utils.unregister_class(VIEW3D_PIE_A02) bpy.utils.unregister_class(VIEW3D_PIE_A03) wm = bpy.context.window_manager if wm.keyconfigs.addon: for km in addon_keymaps: for kmi in km.keymap_items: km.keymap_items.remove(kmi) wm.keyconfigs.addon.keymaps.remove(km) # clear the list del addon_keymaps[:]