# ##### 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 #####
# <pep8 compliant>
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[:]