Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormeta-androcto <meta.androcto1@gmail.com>2016-08-03 16:40:56 +0300
committermeta-androcto <meta.androcto1@gmail.com>2016-08-03 16:40:56 +0300
commit6ee6d9e44aefc6eb1e7cdbf3e8b1e62392f2df6a (patch)
treee68d2c86c2f0ae08e3e54147f38714d11f6578e7 /space_view3d_pie_menus
parent606fbde1c3968d2db1b7beb954a778a4997905c9 (diff)
move 3d view pie menus to release re: T48709
Diffstat (limited to 'space_view3d_pie_menus')
-rw-r--r--space_view3d_pie_menus/__init__.py258
-rw-r--r--space_view3d_pie_menus/pie_align_menu/__init__.py422
-rw-r--r--space_view3d_pie_menus/pie_animation_menu/__init__.py125
-rw-r--r--space_view3d_pie_menus/pie_apply_transform_menu/__init__.py215
-rw-r--r--space_view3d_pie_menus/pie_delete_menu/__init__.py109
-rw-r--r--space_view3d_pie_menus/pie_editor_switch_menu/__init__.py183
-rw-r--r--space_view3d_pie_menus/pie_manipulator_menu/__init__.py233
-rw-r--r--space_view3d_pie_menus/pie_modes_menu/__init__.py397
-rw-r--r--space_view3d_pie_menus/pie_orientation_menu/__init__.py117
-rw-r--r--space_view3d_pie_menus/pie_origin_cursor/__init__.py225
-rw-r--r--space_view3d_pie_menus/pie_pivot_point_menu/__init__.py85
-rw-r--r--space_view3d_pie_menus/pie_proportional_menu/__init__.py468
-rw-r--r--space_view3d_pie_menus/pie_save_open_menu/__init__.py217
-rw-r--r--space_view3d_pie_menus/pie_sculpt_menu/__init__.py180
-rw-r--r--space_view3d_pie_menus/pie_select_menu/__init__.py198
-rw-r--r--space_view3d_pie_menus/pie_shading_menu/__init__.py94
-rw-r--r--space_view3d_pie_menus/pie_snap_menu/__init__.py269
-rw-r--r--space_view3d_pie_menus/pie_views_numpad_menu/__init__.py197
-rw-r--r--space_view3d_pie_menus/utils.py327
19 files changed, 4319 insertions, 0 deletions
diff --git a/space_view3d_pie_menus/__init__.py b/space_view3d_pie_menus/__init__.py
new file mode 100644
index 00000000..e1839dbe
--- /dev/null
+++ b/space_view3d_pie_menus/__init__.py
@@ -0,0 +1,258 @@
+# ##### 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": "3D Viewport Pie Menus",
+ "author": "meta-androcto, pitiwazou, chromoly, italic",
+ "version": (1, 1, 3),
+ "blender": (2, 7, 7),
+ "location": "",
+ "description": "Pie Menu Activate",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
+ "Scripts/3D_interaction/viewport_pies",
+ "tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/",
+ "category": "Pie Menu"
+ }
+
+
+import bpy
+from bpy.props import (
+ BoolProperty,
+ PointerProperty,
+ )
+from bpy.types import (
+ PropertyGroup,
+ AddonPreferences,
+ )
+
+sub_modules_names = (
+ "pie_modes_menu",
+ "pie_views_numpad_menu",
+ "pie_sculpt_menu",
+ "pie_origin_cursor",
+ "pie_manipulator_menu",
+ "pie_snap_menu",
+ "pie_orientation_menu",
+ "pie_shading_menu",
+ "pie_pivot_point_menu",
+ "pie_proportional_menu",
+ "pie_align_menu",
+ "pie_delete_menu",
+ "pie_apply_transform_menu",
+ "pie_select_menu",
+ "pie_animation_menu",
+ "pie_save_open_menu",
+ "pie_editor_switch_menu",
+ )
+
+
+sub_modules = [__import__(__package__ + "." + submod, {}, {}, submod) for submod in sub_modules_names]
+sub_modules.sort(key=lambda mod: (mod.bl_info['category'], mod.bl_info['name']))
+
+
+def _get_pref_class(mod):
+ import inspect
+
+ for obj in vars(mod).values():
+ if inspect.isclass(obj) and issubclass(obj, PropertyGroup):
+ if hasattr(obj, 'bl_idname') and obj.bl_idname == mod.__name__:
+ return obj
+
+
+def get_addon_preferences(name=''):
+ """Acquisition and registration"""
+ addons = bpy.context.user_preferences.addons
+ if __name__ not in addons: # wm.read_factory_settings()
+ return None
+ addon_prefs = addons[__name__].preferences
+ if name:
+ if not hasattr(addon_prefs, name):
+ for mod in sub_modules:
+ if mod.__name__.split('.')[-1] == name:
+ cls = _get_pref_class(mod)
+ if cls:
+ prop = PointerProperty(type=cls)
+ setattr(UIToolsPreferences, name, prop)
+ bpy.utils.unregister_class(UIToolsPreferences)
+ bpy.utils.register_class(UIToolsPreferences)
+ return getattr(addon_prefs, name, None)
+ else:
+ return addon_prefs
+
+
+def register_submodule(mod):
+ if not hasattr(mod, '__addon_enabled__'):
+ mod.__addon_enabled__ = False
+ if not mod.__addon_enabled__:
+ mod.register()
+ mod.__addon_enabled__ = True
+
+
+def unregister_submodule(mod):
+ if mod.__addon_enabled__:
+ mod.unregister()
+ mod.__addon_enabled__ = False
+
+ prefs = get_addon_preferences()
+ name = mod.__name__.split('.')[-1]
+ if hasattr(UIToolsPreferences, name):
+ delattr(UIToolsPreferences, name)
+ if prefs:
+ bpy.utils.unregister_class(UIToolsPreferences)
+ bpy.utils.register_class(UIToolsPreferences)
+ if name in prefs:
+ del prefs[name]
+
+
+class UIToolsPreferences(AddonPreferences):
+ bl_idname = __name__
+
+ def draw(self, context):
+ layout = self.layout
+
+ for mod in sub_modules:
+ mod_name = mod.__name__.split('.')[-1]
+ info = mod.bl_info
+ column = layout.column()
+ box = column.box()
+
+ # first stage
+ expand = getattr(self, 'show_expanded_' + mod_name)
+ icon = 'TRIA_DOWN' if expand else 'TRIA_RIGHT'
+ col = box.column()
+ row = col.row()
+ sub = row.row()
+ sub.context_pointer_set('addon_prefs', self)
+ sub.alignment = 'LEFT'
+ op = sub.operator('wm.context_toggle', text='', icon=icon,
+ emboss=False)
+ op.data_path = 'addon_prefs.show_expanded_' + mod_name
+ sub.label('{}: {}'.format(info['category'], info['name']))
+ sub = row.row()
+ sub.alignment = 'RIGHT'
+ if info.get('warning'):
+ sub.label('', icon='ERROR')
+ sub.prop(self, 'use_' + mod_name, text='')
+
+ # The second stage
+ if expand:
+ if info.get('description'):
+ split = col.row().split(percentage=0.15)
+ split.label('Description:')
+ split.label(info['description'])
+ if info.get('location'):
+ split = col.row().split(percentage=0.15)
+ split.label('Location:')
+ split.label(info['location'])
+ if info.get('author') and info.get('author') != 'chromoly':
+ split = col.row().split(percentage=0.15)
+ split.label('Author:')
+ split.label(info['author'])
+ if info.get('version'):
+ split = col.row().split(percentage=0.15)
+ split.label('Version:')
+ split.label('.'.join(str(x) for x in info['version']),
+ translate=False)
+ if info.get('warning'):
+ split = col.row().split(percentage=0.15)
+ split.label('Warning:')
+ split.label(' ' + info['warning'], icon='ERROR')
+
+ tot_row = int(bool(info.get('wiki_url')))
+ if tot_row:
+ split = col.row().split(percentage=0.15)
+ split.label(text='Internet:')
+ if info.get('wiki_url'):
+ op = split.operator('wm.url_open',
+ text='Documentation', icon='HELP')
+ op.url = info.get('wiki_url')
+ for i in range(4 - tot_row):
+ split.separator()
+
+ # Details and settings
+ if getattr(self, 'use_' + mod_name):
+ prefs = get_addon_preferences(mod_name)
+
+ if prefs and hasattr(prefs, 'draw'):
+ box = box.column()
+ prefs.layout = box
+ try:
+ prefs.draw(context)
+ except:
+ traceback.print_exc()
+ box.label(text='Error (see console)', icon='ERROR')
+ del prefs.layout
+
+ row = layout.row()
+ row.label("End of Pie Menu Activations")
+
+
+for mod in sub_modules:
+ info = mod.bl_info
+ mod_name = mod.__name__.split('.')[-1]
+
+ def gen_update(mod):
+ def update(self, context):
+ if getattr(self, 'use_' + mod.__name__.split('.')[-1]):
+ if not mod.__addon_enabled__:
+ register_submodule(mod)
+ else:
+ if mod.__addon_enabled__:
+ unregister_submodule(mod)
+ return update
+
+ prop = BoolProperty(
+ name=info['name'],
+ description=info.get('description', ''),
+ update=gen_update(mod),
+ )
+ setattr(UIToolsPreferences, 'use_' + mod_name, prop)
+ prop = BoolProperty()
+ setattr(UIToolsPreferences, 'show_expanded_' + mod_name, prop)
+
+classes = (
+ UIToolsPreferences,
+ )
+
+
+def register():
+ for cls in classes:
+ bpy.utils.register_class(cls)
+
+ prefs = get_addon_preferences()
+ for mod in sub_modules:
+ if not hasattr(mod, '__addon_enabled__'):
+ mod.__addon_enabled__ = False
+ name = mod.__name__.split('.')[-1]
+ if getattr(prefs, 'use_' + name):
+ register_submodule(mod)
+
+
+def unregister():
+ for mod in sub_modules:
+ if mod.__addon_enabled__:
+ unregister_submodule(mod)
+
+ for cls in reversed(classes):
+ bpy.utils.unregister_class(cls)
+
+if __name__ == "__main__":
+ register()
diff --git a/space_view3d_pie_menus/pie_align_menu/__init__.py b/space_view3d_pie_menus/pie_align_menu/__init__.py
new file mode 100644
index 00000000..a743c2c3
--- /dev/null
+++ b/space_view3d_pie_menus/pie_align_menu/__init__.py
@@ -0,0 +1,422 @@
+# ##### 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": "Hotkey: 'Alt X'",
+ "description": "V/E/F Align tools",
+ # "author": "pitiwazou, meta-androcto",
+ # "version": (0, 1, 0),
+ "blender": (2, 77, 0),
+ "location": "Mesh Edit Mode",
+ "warning": "",
+ "wiki_url": "",
+ "category": "Edit Align Pie"
+ }
+
+import bpy
+from bpy.types import (
+ Menu,
+ Operator,
+ )
+
+
+# Pie Align - Alt + X
+
+
+class PieAlign(Menu):
+ bl_idname = "pie.align"
+ bl_label = "Pie Align"
+
+ def draw(self, context):
+ layout = self.layout
+ pie = layout.menu_pie()
+ # 4 - LEFT
+ pie.operator("align.x", text="Align X", icon='TRIA_LEFT')
+ # 6 - RIGHT
+ pie.operator("align.z", text="Align Z", icon='TRIA_DOWN')
+ # 2 - BOTTOM
+ pie.operator("align.y", text="Align Y", icon='PLUS')
+ # 8 - TOP
+ pie.operator("align.2y0", text="Align To Y-0")
+ # 7 - TOP - LEFT
+ pie.operator("align.2x0", text="Align To X-0")
+ # 9 - TOP - RIGHT
+ pie.operator("align.2z0", text="Align To Z-0")
+ # 1 - BOTTOM - LEFT
+ # pie.menu("align.xyz")
+ box = pie.split().box().column()
+ row = box.row(align=True)
+ row.label("X")
+ row.operator("alignx.left", text="Neg")
+ row.operator("alignx.right", text="Pos")
+ row = box.row(align=True)
+ row.label("Y")
+ row.operator("aligny.front", text="Neg")
+ row.operator("aligny.back", text="Pos")
+ row = box.row(align=True)
+ row.label("Z")
+ row.operator("alignz.bottom", text="Neg")
+ row.operator("alignz.top", text="Pos")
+ # 3 - BOTTOM - RIGHT
+# box = pie.split().column()
+# row = box.row(align=True)
+# box.operator("mesh.vertex_align", icon='ALIGN', text="Align")
+# box.operator("retopo.space", icon='ALIGN', text="Distribute")
+# box.operator("mesh.vertex_inline", icon='ALIGN', text="Align & Distribute")
+
+# Align X
+
+
+class AlignX(Operator):
+ bl_idname = "align.x"
+ bl_label = "Align X"
+ bl_description = "Align Selected Along X"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+
+ for vert in bpy.context.object.data.vertices:
+ bpy.ops.transform.resize(value=(0, 1, 1), constraint_axis=(True, False, False), constraint_orientation='GLOBAL',
+ mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1)
+ return {'FINISHED'}
+
+# Align Y
+
+
+class AlignY(Operator):
+ bl_idname = "align.y"
+ bl_label = "Align Y"
+ bl_description = "Align Selected Along Y"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+
+ for vert in bpy.context.object.data.vertices:
+ bpy.ops.transform.resize(value=(1, 0, 1), constraint_axis=(False, True, False), constraint_orientation='GLOBAL',
+ mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1)
+ return {'FINISHED'}
+
+# Align Z
+
+
+class AlignZ(Operator):
+ bl_idname = "align.z"
+ bl_label = "Align Z"
+ bl_description = "Align Selected Along Z"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+
+ for vert in bpy.context.object.data.vertices:
+ bpy.ops.transform.resize(value=(1, 1, 0), constraint_axis=(False, False, True), constraint_orientation='GLOBAL',
+ mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1)
+ return {'FINISHED'}
+
+#####################
+# Align To 0 #
+#####################
+
+# Align to X - 0
+
+
+class AlignToX0(Operator):
+ bl_idname = "align.2x0"
+ bl_label = "Align To X = 0"
+ bl_description = "Align Selected To Location X = 0"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ for vert in bpy.context.object.data.vertices:
+ if vert.select:
+ vert.co[0] = 0
+ bpy.ops.object.editmode_toggle()
+ return {'FINISHED'}
+
+# Align to Z - 0
+
+
+class AlignToY0(Operator):
+ bl_idname = "align.2y0"
+ bl_label = "Align To Y = 0"
+ bl_description = "Align Selected To Location Y = 0"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ for vert in bpy.context.object.data.vertices:
+ if vert.select:
+ vert.co[1] = 0
+ bpy.ops.object.editmode_toggle()
+ return {'FINISHED'}
+
+# Align to Z - 0
+
+
+class AlignToZ0(Operator):
+ bl_idname = "align.2z0"
+ bl_label = "Align To Z = 0"
+ bl_description = "Align Selected To Location Z = 0"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ for vert in bpy.context.object.data.vertices:
+ if vert.select:
+ vert.co[2] = 0
+ bpy.ops.object.editmode_toggle()
+ return {'FINISHED'}
+
+# Align X Left
+
+
+class AlignXLeft(Operator):
+ bl_idname = "alignx.left"
+ bl_label = "Align X Left"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ count = 0
+ axe = 0
+ for vert in bpy.context.object.data.vertices:
+ if vert.select:
+ if count == 0:
+ max = vert.co[axe]
+ count += 1
+ continue
+ count += 1
+ if vert.co[axe] < max:
+ max = vert.co[axe]
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ for vert in bpy.context.object.data.vertices:
+ if vert.select:
+ vert.co[axe] = max
+ bpy.ops.object.mode_set(mode='EDIT')
+ return {'FINISHED'}
+
+# Align X Right
+
+
+class AlignXRight(Operator):
+ bl_idname = "alignx.right"
+ bl_label = "Align X Right"
+
+ def execute(self, context):
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ count = 0
+ axe = 0
+ for vert in bpy.context.object.data.vertices:
+ if vert.select:
+ if count == 0:
+ max = vert.co[axe]
+ count += 1
+ continue
+ count += 1
+ if vert.co[axe] > max:
+ max = vert.co[axe]
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ for vert in bpy.context.object.data.vertices:
+ if vert.select:
+ vert.co[axe] = max
+ bpy.ops.object.mode_set(mode='EDIT')
+ return {'FINISHED'}
+
+# Align Y Back
+
+
+class AlignYBack(Operator):
+ bl_idname = "aligny.back"
+ bl_label = "Align Y back"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ count = 0
+ axe = 1
+ for vert in bpy.context.object.data.vertices:
+ if vert.select:
+ if count == 0:
+ max = vert.co[axe]
+ count += 1
+ continue
+ count += 1
+ if vert.co[axe] > max:
+ max = vert.co[axe]
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ for vert in bpy.context.object.data.vertices:
+ if vert.select:
+ vert.co[axe] = max
+ bpy.ops.object.mode_set(mode='EDIT')
+ return {'FINISHED'}
+
+# Align Y Front
+
+
+class AlignYFront(Operator):
+ bl_idname = "aligny.front"
+ bl_label = "Align Y Front"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ count = 0
+ axe = 1
+ for vert in bpy.context.object.data.vertices:
+ if vert.select:
+ if count == 0:
+ max = vert.co[axe]
+ count += 1
+ continue
+ count += 1
+ if vert.co[axe] < max:
+ max = vert.co[axe]
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ for vert in bpy.context.object.data.vertices:
+ if vert.select:
+ vert.co[axe] = max
+ bpy.ops.object.mode_set(mode='EDIT')
+ return {'FINISHED'}
+
+# Align Z Top
+
+
+class AlignZTop(Operator):
+ bl_idname = "alignz.top"
+ bl_label = "Align Z Top"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ count = 0
+ axe = 2
+ for vert in bpy.context.object.data.vertices:
+ if vert.select:
+ if count == 0:
+ max = vert.co[axe]
+ count += 1
+ continue
+ count += 1
+ if vert.co[axe] > max:
+ max = vert.co[axe]
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ for vert in bpy.context.object.data.vertices:
+ if vert.select:
+ vert.co[axe] = max
+ bpy.ops.object.mode_set(mode='EDIT')
+ return {'FINISHED'}
+
+# Align Z Bottom
+
+
+class AlignZBottom(Operator):
+ bl_idname = "alignz.bottom"
+ bl_label = "Align Z Bottom"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ count = 0
+ axe = 2
+ for vert in bpy.context.object.data.vertices:
+ if vert.select:
+ if count == 0:
+ max = vert.co[axe]
+ count += 1
+ continue
+ count += 1
+ if vert.co[axe] < max:
+ max = vert.co[axe]
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ for vert in bpy.context.object.data.vertices:
+ if vert.select:
+ vert.co[axe] = max
+ bpy.ops.object.mode_set(mode='EDIT')
+ return {'FINISHED'}
+
+classes = (
+ PieAlign,
+ AlignX,
+ AlignY,
+ AlignZ,
+ AlignToX0,
+ AlignToY0,
+ AlignToZ0,
+ AlignXLeft,
+ AlignXRight,
+ AlignYBack,
+ AlignYFront,
+ AlignZTop,
+ AlignZBottom,
+ )
+
+addon_keymaps = []
+
+
+def register():
+ for cls in classes:
+ bpy.utils.register_class(cls)
+ wm = bpy.context.window_manager
+
+ if wm.keyconfigs.addon:
+ # Align
+ km = wm.keyconfigs.addon.keymaps.new(name='Mesh')
+ kmi = km.keymap_items.new('wm.call_menu_pie', 'X', 'PRESS', alt=True)
+ kmi.properties.name = "pie.align"
+# kmi.active = True
+ addon_keymaps.append((km, kmi))
+
+
+def unregister():
+ for cls in classes:
+ bpy.utils.unregister_class(cls)
+ wm = bpy.context.window_manager
+
+ kc = wm.keyconfigs.addon
+ if kc:
+ km = kc.keymaps['Mesh']
+ for kmi in km.keymap_items:
+ if kmi.idname == 'wm.call_menu_pie':
+ if kmi.properties.name == "pie.align":
+ km.keymap_items.remove(kmi)
+
+if __name__ == "__main__":
+ register()
diff --git a/space_view3d_pie_menus/pie_animation_menu/__init__.py b/space_view3d_pie_menus/pie_animation_menu/__init__.py
new file mode 100644
index 00000000..9c2b6042
--- /dev/null
+++ b/space_view3d_pie_menus/pie_animation_menu/__init__.py
@@ -0,0 +1,125 @@
+# ##### 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": "Hotkey: 'Alt A'",
+ "description": "Pie menu for Timeline controls",
+ # "author": "pitiwazou, meta-androcto",
+ # "version": (0, 1, 0),
+ "blender": (2, 77, 0),
+ "location": "3D View",
+ "warning": "",
+ "wiki_url": "",
+ "category": "Animation Pie"
+ }
+
+import bpy
+from bpy.types import (
+ Menu,
+ Operator,
+ )
+
+# Pie Animation
+
+
+class PieAnimation(Menu):
+ bl_idname = "pie.animation"
+ bl_label = "Pie Animation"
+
+ def draw(self, context):
+ layout = self.layout
+ pie = layout.menu_pie()
+ # 4 - LEFT
+ pie.operator("screen.frame_jump", text="Jump REW", icon='REW').end = False
+ # 6 - RIGHT
+ pie.operator("screen.frame_jump", text="Jump FF", icon='FF').end = True
+ # 2 - BOTTOM
+ pie.operator("screen.animation_play", text="Reverse", icon='PLAY_REVERSE').reverse = True
+ # 8 - TOP
+ if not context.screen.is_animation_playing: # Play / Pause
+ pie.operator("screen.animation_play", text="Play", icon='PLAY')
+ else:
+ pie.operator("screen.animation_play", text="Stop", icon='PAUSE')
+ # 7 - TOP - LEFT
+ pie.operator("screen.keyframe_jump", text="Previous FR", icon='PREV_KEYFRAME').next = False
+ # 9 - TOP - RIGHT
+ pie.operator("screen.keyframe_jump", text="Next FR", icon='NEXT_KEYFRAME').next = True
+ # 1 - BOTTOM - LEFT
+ pie.operator("insert.autokeyframe", text="Auto Keyframe ", icon='REC')
+ # 3 - BOTTOM - RIGHT
+ pie.menu("VIEW3D_MT_object_animation", icon="CLIP")
+
+
+# Insert Auto Keyframe
+class InsertAutoKeyframe(Operator):
+ bl_idname = "insert.autokeyframe"
+ bl_label = "Insert Auto Keyframe"
+ bl_description = "Toggle Insert Auto Keyframe"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+
+ ts.use_keyframe_insert_auto ^= 1
+
+ for area in context.screen.areas:
+ if area.type in ('TIMELINE'):
+ area.tag_redraw()
+
+ return {'FINISHED'}
+
+classes = (
+ PieAnimation,
+ InsertAutoKeyframe
+ )
+
+addon_keymaps = []
+
+
+def register():
+ for cls in classes:
+ bpy.utils.register_class(cls)
+ wm = bpy.context.window_manager
+
+ if wm.keyconfigs.addon:
+ # Animation
+ km = wm.keyconfigs.addon.keymaps.new(name='Object Non-modal')
+ kmi = km.keymap_items.new('wm.call_menu_pie', 'A', 'PRESS', alt=True)
+ kmi.properties.name = "pie.animation"
+ # kmi.active = True
+ addon_keymaps.append((km, kmi))
+
+
+def unregister():
+ for cls in classes:
+ bpy.utils.unregister_class(cls)
+ wm = bpy.context.window_manager
+
+ kc = wm.keyconfigs.addon
+ if kc:
+ km = kc.keymaps['Object Non-modal']
+ for kmi in km.keymap_items:
+ if kmi.idname == 'wm.call_menu_pie':
+ if kmi.properties.name == "pie.animation":
+ km.keymap_items.remove(kmi)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/space_view3d_pie_menus/pie_apply_transform_menu/__init__.py b/space_view3d_pie_menus/pie_apply_transform_menu/__init__.py
new file mode 100644
index 00000000..a3f9e519
--- /dev/null
+++ b/space_view3d_pie_menus/pie_apply_transform_menu/__init__.py
@@ -0,0 +1,215 @@
+# ##### 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": "Hotkey: 'Ctrl A'",
+ "description": "Apply Transform Menu",
+ # "author": "pitiwazou, meta-androcto",
+ # "version": (0, 1, 0),
+ "blender": (2, 77, 0),
+ "location": "3D View",
+ "warning": "",
+ "wiki_url": "",
+ "category": "Apply Transform Pie"
+ }
+
+import bpy
+from bpy.types import (
+ Menu,
+ Operator,
+ )
+
+# Pie Apply Transforms - Ctrl + A
+
+
+class PieApplyTransforms(Menu):
+ bl_idname = "pie.applytranforms"
+ bl_label = "Pie Apply Transforms"
+
+ def draw(self, context):
+ layout = self.layout
+ pie = layout.menu_pie()
+ # 4 - LEFT
+ pie.operator("apply.transformall", text="Apply All", icon='FREEZE')
+ # 6 - RIGHT
+ pie.operator("clear.all", text="Clear All", icon='MANIPUL')
+ # 2 - BOTTOM
+ pie.menu("applymore.menu", text="More")
+ # 8 - TOP
+ pie.operator("apply.transformrotation", text="Rotation", icon='MAN_ROT')
+ # 7 - TOP - LEFT
+ pie.operator("apply.transformlocation", text="Location", icon='MAN_TRANS')
+ # 9 - TOP - RIGHT
+ pie.operator("apply.transformscale", text="Scale", icon='MAN_SCALE')
+ # 1 - BOTTOM - LEFT
+ pie.operator("apply.transformrotationscale", text="Rotation/Scale")
+ # 3 - BOTTOM - RIGHT
+ pie.menu("clear.menu", text="Clear Transforms")
+
+# Apply Transforms
+
+
+class ApplyTransformLocation(Operator):
+ bl_idname = "apply.transformlocation"
+ bl_label = "Apply Transform Location"
+ bl_description = "Apply Transform Location"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ bpy.ops.object.transform_apply(location=True, rotation=False, scale=False)
+ return {'FINISHED'}
+
+# Apply Transforms
+
+
+class ApplyTransformRotation(Operator):
+ bl_idname = "apply.transformrotation"
+ bl_label = "Apply Transform Rotation"
+ bl_description = "Apply Transform Rotation"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ bpy.ops.object.transform_apply(location=False, rotation=True, scale=False)
+ return {'FINISHED'}
+
+# Apply Transforms
+
+
+class ApplyTransformScale(Operator):
+ bl_idname = "apply.transformscale"
+ bl_label = "Apply Transform Scale"
+ bl_description = "Apply Transform Scale"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
+ return {'FINISHED'}
+
+# Apply Transforms
+
+
+class ApplyTransformRotationScale(Operator):
+ bl_idname = "apply.transformrotationscale"
+ bl_label = "Apply Transform Rotation Scale"
+ bl_description = "Apply Transform Rotation Scale"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)
+ return {'FINISHED'}
+
+# Apply Transforms
+
+
+class ApplyTransformAll(Operator):
+ bl_idname = "apply.transformall"
+ bl_label = "Apply All Transforms"
+ bl_description = "Apply Transform All"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
+ return {'FINISHED'}
+
+# More Menu
+
+
+class TransformApplyMore(Menu):
+ bl_idname = "applymore.menu"
+ bl_label = "More Menu"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator("object.visual_transform_apply", text="Visual Transforms")
+ layout.operator("object.duplicates_make_real", text="Make Duplicates Real")
+
+# Clear Menu
+
+
+class ClearMenu(Menu):
+ bl_idname = "clear.menu"
+ bl_label = "Clear Menu"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator("object.location_clear", text="Clear Location", icon='MAN_TRANS')
+ layout.operator("object.rotation_clear", text="Clear Rotation", icon='MAN_ROT')
+ layout.operator("object.scale_clear", text="Clear Scale", icon='MAN_SCALE')
+ layout.operator("object.origin_clear", text="Clear Origin", icon='MANIPUL')
+
+# Clear all
+
+
+class ClearAll(Operator):
+ bl_idname = "clear.all"
+ bl_label = "Clear All"
+ bl_description = "Clear All Transforms"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ bpy.ops.object.location_clear()
+ bpy.ops.object.rotation_clear()
+ bpy.ops.object.scale_clear()
+ return {'FINISHED'}
+
+classes = (
+ PieApplyTransforms,
+ ApplyTransformLocation,
+ ApplyTransformRotation,
+ ApplyTransformScale,
+ ApplyTransformRotationScale,
+ ApplyTransformAll,
+ ClearMenu,
+ ClearAll,
+ TransformApplyMore,
+ )
+
+addon_keymaps = []
+
+
+def register():
+ for cls in classes:
+ bpy.utils.register_class(cls)
+ wm = bpy.context.window_manager
+
+ if wm.keyconfigs.addon:
+ # Apply Transform
+ km = wm.keyconfigs.addon.keymaps.new(name='Object Mode')
+ kmi = km.keymap_items.new('wm.call_menu_pie', 'A', 'PRESS', ctrl=True)
+ kmi.properties.name = "pie.applytranforms"
+# kmi.active = True
+ addon_keymaps.append((km, kmi))
+
+
+def unregister():
+ for cls in classes:
+ bpy.utils.unregister_class(cls)
+ wm = bpy.context.window_manager
+
+ kc = wm.keyconfigs.addon
+ if kc:
+ km = kc.keymaps['Object Mode']
+ for kmi in km.keymap_items:
+ if kmi.idname == 'wm.call_menu_pie':
+ if kmi.properties.name == "pie.applytranforms":
+ km.keymap_items.remove(kmi)
+
+if __name__ == "__main__":
+ register()
diff --git a/space_view3d_pie_menus/pie_delete_menu/__init__.py b/space_view3d_pie_menus/pie_delete_menu/__init__.py
new file mode 100644
index 00000000..f804c877
--- /dev/null
+++ b/space_view3d_pie_menus/pie_delete_menu/__init__.py
@@ -0,0 +1,109 @@
+# ##### 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": "Hotkey: 'X'",
+ "description": "Edit mode V/E/F Delete Modes",
+ # "author": "pitiwazou, meta-androcto",
+ # "version": (0, 1, 0),
+ "blender": (2, 77, 0),
+ "location": "Mesh Edit Mode",
+ "warning": "",
+ "wiki_url": "",
+ "category": "Edit Delete Pie"
+ }
+
+import bpy
+from bpy.types import (
+ Menu,
+ Operator,
+ )
+
+# Pie Delete - X
+
+
+class PieDelete(Menu):
+ bl_idname = "pie.delete"
+ bl_label = "Pie Delete"
+
+ def draw(self, context):
+ layout = self.layout
+ pie = layout.menu_pie()
+ # 4 - LEFT
+ pie.operator("mesh.delete", text="Delete Vertices", icon='VERTEXSEL').type = 'VERT'
+ # 6 - RIGHT
+ pie.operator("mesh.delete", text="Delete Faces", icon='FACESEL').type = 'FACE'
+ # 2 - BOTTOM
+ pie.operator("mesh.delete", text="Delete Edges", icon='EDGESEL').type = 'EDGE'
+ # 8 - TOP
+ pie.operator("mesh.dissolve_edges", text="Dissolve Edges", icon='SNAP_EDGE')
+ # 7 - TOP - LEFT
+ pie.operator("mesh.dissolve_verts", text="Dissolve Vertices", icon='SNAP_VERTEX')
+ # 9 - TOP - RIGHT
+ pie.operator("mesh.dissolve_faces", text="Dissolve Faces", icon='SNAP_FACE')
+ # 1 - BOTTOM - LEFT
+ box = pie.split().column()
+ row = box.row(align=True)
+ box.operator("mesh.dissolve_limited", text="Limited Dissolve", icon='STICKY_UVS_LOC')
+ box.operator("mesh.delete_edgeloop", text="Delete Edge Loops", icon='BORDER_LASSO')
+ box.operator("mesh.edge_collapse", text="Edge Collapse", icon='UV_EDGESEL')
+ # 3 - BOTTOM - RIGHT
+ box = pie.split().column()
+ row = box.row(align=True)
+ box.operator("mesh.delete", text="Only Edge & Faces", icon='SPACE2').type = 'EDGE_FACE'
+ box.operator("mesh.delete", text="Only Faces", icon='UV_FACESEL').type = 'ONLY_FACE'
+ box.operator("mesh.remove_doubles", text="Remove Doubles", icon='ORTHO')
+
+classes = (
+ PieDelete,
+ )
+
+addon_keymaps = []
+
+
+def register():
+ for cls in classes:
+ bpy.utils.register_class(cls)
+ wm = bpy.context.window_manager
+
+ if wm.keyconfigs.addon:
+ # Delete
+ km = wm.keyconfigs.addon.keymaps.new(name='Mesh')
+ kmi = km.keymap_items.new('wm.call_menu_pie', 'X', 'PRESS')
+ kmi.properties.name = "pie.delete"
+# kmi.active = True
+ addon_keymaps.append((km, kmi))
+
+
+def unregister():
+ for cls in classes:
+ bpy.utils.unregister_class(cls)
+ wm = bpy.context.window_manager
+
+ kc = wm.keyconfigs.addon
+ if kc:
+ km = kc.keymaps['Mesh']
+ for kmi in km.keymap_items:
+ if kmi.idname == 'wm.call_menu_pie':
+ if kmi.properties.name == "pie.delete":
+ km.keymap_items.remove(kmi)
+
+if __name__ == "__main__":
+ register()
diff --git a/space_view3d_pie_menus/pie_editor_switch_menu/__init__.py b/space_view3d_pie_menus/pie_editor_switch_menu/__init__.py
new file mode 100644
index 00000000..2f206bf4
--- /dev/null
+++ b/space_view3d_pie_menus/pie_editor_switch_menu/__init__.py
@@ -0,0 +1,183 @@
+# ##### 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": "Hotkey: 'Ctrl Alt S ",
+ "description": "Switch Editor Type Menu",
+ # "author": "saidenka",
+ # "version": (0, 1, 0),
+ "blender": (2, 77, 0),
+ "location": "All Editors",
+ "warning": "",
+ "wiki_url": "",
+ "category": "Editor Switch Pie"
+ }
+
+import bpy
+from bpy.types import (
+ Menu,
+ Operator,
+ )
+from bpy.props import (
+ StringProperty,
+ )
+
+
+class AreaPieMenu(Menu):
+ bl_idname = "INFO_MT_window_pie"
+ bl_label = "Pie Menu"
+ bl_description = "Window Pie Menus"
+
+ def draw(self, context):
+ self.layout.operator(AreaTypePieOperator.bl_idname, icon="PLUGIN")
+
+
+class AreaTypePieOperator(Operator):
+ bl_idname = "wm.area_type_pie_operator"
+ bl_label = "Editor Type"
+ bl_description = "This is pie menu of editor type change"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ bpy.ops.wm.call_menu_pie(name=AreaTypeEditor.bl_idname)
+ return {'FINISHED'}
+
+
+class AreaPieEditor(Menu):
+ bl_idname = "pie.editor"
+ bl_label = "Editor Switch"
+
+ def draw(self, context):
+ # 4 - LEFT
+ self.layout.menu_pie().operator(SetAreaType.bl_idname, text="Text Editor", icon="TEXT").type = "TEXT_EDITOR"
+ # 6 - RIGHT
+ self.layout.menu_pie().operator(SetAreaType.bl_idname, text="Outliner", icon="OOPS").type = "OUTLINER"
+ # 2 - BOTTOM
+ self.layout.menu_pie().operator("wm.call_menu_pie", text="More Types", icon="QUESTION").name = AreaTypePieOther.bl_idname
+ # 8 - TOP
+ self.layout.menu_pie().operator(SetAreaType.bl_idname, text="3D View", icon="MESH_CUBE").type = "VIEW_3D"
+ # 7 - TOP - LEFT
+ self.layout.menu_pie().operator(SetAreaType.bl_idname, text="UV/Image Editor", icon="IMAGE_COL").type = "IMAGE_EDITOR"
+ # 9 - TOP - RIGHT
+ self.layout.menu_pie().operator(SetAreaType.bl_idname, text="Node Editor", icon="NODETREE").type = "NODE_EDITOR"
+ # 1 - BOTTOM - LEFT
+ self.layout.menu_pie().operator("wm.call_menu_pie", text="Animation Pie", icon="ACTION").name = AreaTypePieAnim.bl_idname
+ # 3 - BOTTOM - RIGHT
+ self.layout.menu_pie().operator(SetAreaType.bl_idname, text="Property", icon="BUTS").type = "PROPERTIES"
+
+
+class AreaTypePieOther(Menu):
+ bl_idname = "INFO_MT_window_pie_area_type_other"
+ bl_label = "Editor Type (other)"
+ bl_description = "Is pie menu change editor type (other)"
+
+ def draw(self, context):
+ # 4 - LEFT
+ self.layout.menu_pie().operator(SetAreaType.bl_idname, text="Logic Editor", icon="LOGIC").type = "LOGIC_EDITOR"
+ # 6 - RIGHT
+ self.layout.menu_pie().operator(SetAreaType.bl_idname, text="File Browser", icon="FILESEL").type = "FILE_BROWSER"
+ # 2 - BOTTOM
+ self.layout.menu_pie().operator(SetAreaType.bl_idname, text="Python Console", icon="CONSOLE").type = "CONSOLE"
+ # 8 - TOP
+ self.layout.menu_pie().operator("wm.call_menu_pie", text="Back", icon="BACK").name = AreaPieEditor.bl_idname
+ # 7 - TOP - LEFT
+ self.layout.menu_pie().operator(SetAreaType.bl_idname, text="User Setting", icon="PREFERENCES").type = "USER_PREFERENCES"
+ # 9 - TOP - RIGHT
+ self.layout.menu_pie().operator(SetAreaType.bl_idname, text="Info", icon="INFO").type = "INFO"
+ # 1 - BOTTOM - LEFT
+ # 3 - BOTTOM - RIGHT
+
+
+class SetAreaType(Operator):
+ bl_idname = "wm.set_area_type"
+ bl_label = "Change Editor Type"
+ bl_description = "Change Editor Type"
+ bl_options = {'REGISTER'}
+
+ type = StringProperty(name="Area Type")
+
+ def execute(self, context):
+ context.area.type = self.type
+ return {'FINISHED'}
+
+
+class AreaTypePieAnim(Menu):
+ bl_idname = "INFO_MT_window_pie_area_type_anim"
+ bl_label = "Editor Type (Animation)"
+ bl_description = "Is pie menu change editor type (animation related)"
+
+ def draw(self, context):
+ # 4 - LEFT
+ self.layout.menu_pie().operator(SetAreaType.bl_idname, text="NLA Editor", icon="NLA").type = "NLA_EDITOR"
+ # 6 - RIGHT
+ self.layout.menu_pie().operator(SetAreaType.bl_idname, text="DopeSheet", icon="ACTION").type = "DOPESHEET_EDITOR"
+ # 2 - BOTTOM
+ self.layout.menu_pie().operator(SetAreaType.bl_idname, text="Graph Editor", icon="IPO").type = "GRAPH_EDITOR"
+ # 8 - TOP
+ self.layout.menu_pie().operator(SetAreaType.bl_idname, text="Timeline", icon="TIME").type = "TIMELINE"
+ # 7 - TOP - LEFT
+ self.layout.menu_pie().operator(SetAreaType.bl_idname, text="Video Sequence Editor", icon="SEQUENCE").type = "SEQUENCE_EDITOR"
+ # 9 - TOP - RIGHT
+ self.layout.menu_pie().operator(SetAreaType.bl_idname, text="Video Clip Editor", icon="RENDER_ANIMATION").type = "CLIP_EDITOR"
+ # 1 - BOTTOM - LEFT
+ self.layout.menu_pie().operator("wm.call_menu_pie", text="Back", icon="BACK").name = PieEditor.bl_idname
+ # 3 - BOTTOM - RIGHT
+
+classes = (
+ AreaPieMenu,
+ AreaTypePieOperator,
+ AreaPieEditor,
+ AreaTypePieOther,
+ SetAreaType,
+ AreaTypePieAnim,
+ )
+
+addon_keymaps = []
+
+
+def register():
+ for cls in classes:
+ bpy.utils.register_class(cls)
+ wm = bpy.context.window_manager
+
+ if wm.keyconfigs.addon:
+ # Snapping
+ km = wm.keyconfigs.addon.keymaps.new(name='Window')
+ kmi = km.keymap_items.new('wm.call_menu_pie', 'S', 'PRESS', ctrl=True, alt=True)
+ kmi.properties.name = "pie.editor"
+# kmi.active = True
+ addon_keymaps.append((km, kmi))
+
+
+def unregister():
+ for cls in classes:
+ bpy.utils.unregister_class(cls)
+ wm = bpy.context.window_manager
+
+ kc = wm.keyconfigs.addon
+ if kc:
+ km = kc.keymaps['Window']
+ for kmi in km.keymap_items:
+ if kmi.idname == 'wm.call_menu_pie':
+ if kmi.properties.name == "wm.area_type_pie_operator":
+ km.keymap_items.remove(kmi)
+
+if __name__ == "__main__":
+ register()
diff --git a/space_view3d_pie_menus/pie_manipulator_menu/__init__.py b/space_view3d_pie_menus/pie_manipulator_menu/__init__.py
new file mode 100644
index 00000000..2e3de4cf
--- /dev/null
+++ b/space_view3d_pie_menus/pie_manipulator_menu/__init__.py
@@ -0,0 +1,233 @@
+# ##### 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": "Hotkey: 'Ctrl Space'",
+ "description": "Extended Manipulator Menu",
+ # "author": "pitiwazou, meta-androcto",
+ # "version": (0, 1, 0),
+ "blender": (2, 77, 0),
+ "location": "3D View",
+ "warning": "",
+ "wiki_url": "",
+ "category": "Manipulator Pie"
+ }
+
+import bpy
+from bpy.types import (
+ Menu,
+ Operator,
+ )
+
+
+class ManipTranslate(Operator):
+ bl_idname = "manip.translate"
+ bl_label = "Manip Translate"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = " Show Translate"
+
+ def execute(self, context):
+ if context.space_data.show_manipulator == False:
+ context.space_data.show_manipulator = True
+ context.space_data.transform_manipulators = {'TRANSLATE'}
+ if context.space_data.transform_manipulators != {'TRANSLATE'}:
+ context.space_data.transform_manipulators = {'TRANSLATE'}
+ return {'FINISHED'}
+
+
+class ManipRotate(Operator):
+ bl_idname = "manip.rotate"
+ bl_label = "Manip Rotate"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = " Show Rotate"
+
+ def execute(self, context):
+ if context.space_data.show_manipulator == False:
+ context.space_data.show_manipulator = True
+ context.space_data.transform_manipulators = {'ROTATE'}
+ if context.space_data.transform_manipulators != {'ROTATE'}:
+ context.space_data.transform_manipulators = {'ROTATE'}
+ return {'FINISHED'}
+
+
+class ManipScale(Operator):
+ bl_idname = "manip.scale"
+ bl_label = "Manip Scale"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = " Show Scale"
+
+ def execute(self, context):
+ if context.space_data.show_manipulator == False:
+ context.space_data.show_manipulator = True
+ context.space_data.transform_manipulators = {'SCALE'}
+ if context.space_data.transform_manipulators != {'SCALE'}:
+ context.space_data.transform_manipulators = {'SCALE'}
+ return {'FINISHED'}
+
+
+class TranslateRotate(Operator):
+ bl_idname = "translate.rotate"
+ bl_label = "Translate Rotate"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = " Show Translate/Rotate"
+
+ def execute(self, context):
+ if context.space_data.show_manipulator == False:
+ context.space_data.show_manipulator = True
+ context.space_data.transform_manipulators = {'TRANSLATE', 'ROTATE'}
+ if context.space_data.transform_manipulators != {'TRANSLATE', 'ROTATE'}:
+ context.space_data.transform_manipulators = {'TRANSLATE', 'ROTATE'}
+ return {'FINISHED'}
+
+
+class TranslateScale(Operator):
+ bl_idname = "translate.scale"
+ bl_label = "Translate Scale"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = " Show Translate/Scale"
+
+ def execute(self, context):
+ if context.space_data.show_manipulator == False:
+ context.space_data.show_manipulator = True
+ context.space_data.transform_manipulators = {'TRANSLATE', 'SCALE'}
+ if context.space_data.transform_manipulators != {'TRANSLATE', 'SCALE'}:
+ context.space_data.transform_manipulators = {'TRANSLATE', 'SCALE'}
+ return {'FINISHED'}
+
+
+class RotateScale(Operator):
+ bl_idname = "rotate.scale"
+ bl_label = "Rotate Scale"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = " Show Rotate/Scale"
+
+ def execute(self, context):
+ if context.space_data.show_manipulator == False:
+ context.space_data.show_manipulator = True
+ context.space_data.transform_manipulators = {'ROTATE', 'SCALE'}
+ if context.space_data.transform_manipulators != {'ROTATE', 'SCALE'}:
+ context.space_data.transform_manipulators = {'ROTATE', 'SCALE'}
+ return {'FINISHED'}
+
+
+class TranslateRotateScale(Operator):
+ bl_idname = "translate.rotatescale"
+ bl_label = "Translate Rotate Scale"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "Show All"
+
+ def execute(self, context):
+ if context.space_data.show_manipulator == False:
+ context.space_data.show_manipulator = True
+ context.space_data.transform_manipulators = {'TRANSLATE', 'ROTATE', 'SCALE'}
+ if context.space_data.transform_manipulators != {'TRANSLATE', 'ROTATE', 'SCALE'}:
+ context.space_data.transform_manipulators = {'TRANSLATE', 'ROTATE', 'SCALE'}
+ return {'FINISHED'}
+
+
+class WManupulators(Operator):
+ bl_idname = "w.manupulators"
+ bl_label = "W Manupulators"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = " Show/Hide Manipulator"
+
+ def execute(self, context):
+
+ if context.space_data.show_manipulator == True:
+ context.space_data.show_manipulator = False
+
+ elif context.space_data.show_manipulator == False:
+ context.space_data.show_manipulator = True
+
+ return {'FINISHED'}
+
+# Pie Manipulators - Ctrl + Space
+
+
+class PieManipulator(Menu):
+ bl_idname = "pie.manipulator"
+ bl_label = "Pie Manipulator"
+
+ def draw(self, context):
+ layout = self.layout
+ pie = layout.menu_pie()
+ # 4 - LEFT
+ pie.operator("rotate.scale", text="Rotate/Scale")
+ # 6 - RIGHT
+ pie.operator("manip.rotate", text="Rotate", icon='MAN_ROT')
+ # 2 - BOTTOM
+ pie.operator("translate.rotatescale", text="Translate/Rotate/Scale")
+ # 8 - TOP
+ pie.operator("w.manupulators", text="Show/Hide Toggle", icon='MANIPUL')
+ # 7 - TOP - LEFT
+ pie.operator("translate.rotate", text="Translate/Rotate")
+ # 9 - TOP - RIGHT
+ pie.operator("manip.translate", text="Translate", icon='MAN_TRANS')
+ # 1 - BOTTOM - LEFT
+ pie.operator("translate.scale", text="Translate/Scale")
+ # 3 - BOTTOM - RIGHT
+ pie.operator("manip.scale", text="Scale", icon='MAN_SCALE')
+
+# Pie Snapping - Shift + Tab
+
+classes = (
+ PieManipulator,
+ ManipTranslate,
+ ManipRotate,
+ ManipScale,
+ TranslateRotate,
+ TranslateScale,
+ RotateScale,
+ TranslateRotateScale,
+ WManupulators,
+ )
+
+addon_keymaps = []
+
+
+def register():
+ for cls in classes:
+ bpy.utils.register_class(cls)
+ wm = bpy.context.window_manager
+
+ if wm.keyconfigs.addon:
+ # Manipulators
+ km = wm.keyconfigs.addon.keymaps.new(name='3D View Generic', space_type='VIEW_3D')
+ kmi = km.keymap_items.new('wm.call_menu_pie', 'SPACE', 'PRESS', ctrl=True)
+ kmi.properties.name = "pie.manipulator"
+# kmi.active = True
+ addon_keymaps.append((km, kmi))
+
+
+def unregister():
+ for cls in classes:
+ bpy.utils.unregister_class(cls)
+ wm = bpy.context.window_manager
+
+ kc = wm.keyconfigs.addon
+ if kc:
+ km = kc.keymaps['3D View Generic']
+ for kmi in km.keymap_items:
+ if kmi.idname == 'wm.call_menu_pie':
+ if kmi.properties.name == "pie.manipulator":
+ km.keymap_items.remove(kmi)
+
+if __name__ == "__main__":
+ register()
diff --git a/space_view3d_pie_menus/pie_modes_menu/__init__.py b/space_view3d_pie_menus/pie_modes_menu/__init__.py
new file mode 100644
index 00000000..01fde97a
--- /dev/null
+++ b/space_view3d_pie_menus/pie_modes_menu/__init__.py
@@ -0,0 +1,397 @@
+# ##### 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": "Hotkey: 'Tab'",
+ "description": "Switch between 3d view object/edit modes",
+ # "author": "pitiwazou, meta-androcto",
+ # "version": (0, 1, 0),
+ "blender": (2, 77, 0),
+ "location": "3D View",
+ "warning": "",
+ "wiki_url": "",
+ "category": "Mode Switch Pie"
+ }
+
+import bpy
+from bpy.types import (
+ Menu,
+ Operator,
+ )
+
+# Define Class Object Mode
+
+
+class ClassObject(Operator):
+ bl_idname = "class.object"
+ bl_label = "Class Object"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "Edit/Object Mode Switch"
+
+ def execute(self, context):
+
+ if context.object.mode == "OBJECT":
+ bpy.ops.object.mode_set(mode="EDIT")
+ else:
+ bpy.ops.object.mode_set(mode="OBJECT")
+ return {'FINISHED'}
+
+# Define Class Vertex
+
+
+class ClassVertex(Operator):
+ bl_idname = "class.vertex"
+ bl_label = "Class Vertex"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "Vert Select"
+
+ def execute(self, context):
+
+ if context.object.mode != "EDIT":
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
+ if bpy.ops.mesh.select_mode != "EDGE, FACE":
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
+ return {'FINISHED'}
+
+# Define Class Edge
+
+
+class ClassEdge(Operator):
+ bl_idname = "class.edge"
+ bl_label = "Class Edge"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "Edge Select"
+
+ def execute(self, context):
+
+ if context.object.mode != "EDIT":
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
+ if bpy.ops.mesh.select_mode != "VERT, FACE":
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
+ return {'FINISHED'}
+
+# Define Class Face
+
+
+class ClassFace(Operator):
+ bl_idname = "class.face"
+ bl_label = "Class Face"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "Face Select"
+
+ def execute(self, context):
+
+ if context.object.mode != "EDIT":
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='FACE')
+ if bpy.ops.mesh.select_mode != "VERT, EDGE":
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='FACE')
+ return {'FINISHED'}
+# Define Class Texture Paint
+
+
+class ClassTexturePaint(Operator):
+ bl_idname = "class.pietexturepaint"
+ bl_label = "Class Texture Paint"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "Texture Paint"
+
+ def execute(self, context):
+
+ if context.object.mode == "EDIT":
+ bpy.ops.object.mode_set(mode="OBJECT")
+ bpy.ops.paint.texture_paint_toggle()
+ else:
+ bpy.ops.paint.texture_paint_toggle()
+ return {'FINISHED'}
+
+# Define Class Weight Paint
+
+
+class ClassWeightPaint(Operator):
+ bl_idname = "class.pieweightpaint"
+ bl_label = "Class Weight Paint"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "Weight Paint"
+
+ def execute(self, context):
+
+ if context.object.mode == "EDIT":
+ bpy.ops.object.mode_set(mode="OBJECT")
+ bpy.ops.paint.weight_paint_toggle()
+ else:
+ bpy.ops.paint.weight_paint_toggle()
+ return {'FINISHED'}
+
+# Define Class Vertex Paint
+
+
+class ClassVertexPaint(Operator):
+ bl_idname = "class.pievertexpaint"
+ bl_label = "Class Vertex Paint"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "Vertex Paint"
+
+ def execute(self, context):
+
+ if context.object.mode == "EDIT":
+ bpy.ops.object.mode_set(mode="OBJECT")
+ bpy.ops.paint.vertex_paint_toggle()
+ else:
+ bpy.ops.paint.vertex_paint_toggle()
+ return {'FINISHED'}
+
+# Define Class Particle Edit
+
+
+class ClassParticleEdit(Operator):
+ bl_idname = "class.pieparticleedit"
+ bl_label = "Class Particle Edit"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "Particle Edit (must have active particle system)"
+
+ def execute(self, context):
+
+ if context.object.mode == "EDIT":
+ bpy.ops.object.mode_set(mode="OBJECT")
+ bpy.ops.particle.particle_edit_toggle()
+ else:
+ bpy.ops.particle.particle_edit_toggle()
+
+ return {'FINISHED'}
+
+# Components Selection Mode
+
+
+class VertsEdges(Operator):
+ bl_idname = "verts.edges"
+ bl_label = "Verts Edges"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "Vert/Edge Select"
+
+ def execute(self, context):
+ if context.object.mode != "EDIT":
+ bpy.ops.object.mode_set(mode="EDIT")
+ context.tool_settings.mesh_select_mode = (True, True, False)
+ if context.object.mode == "EDIT":
+ context.tool_settings.mesh_select_mode = (True, True, False)
+ return {'FINISHED'}
+
+
+class EdgesFaces(Operator):
+ bl_idname = "edges.faces"
+ bl_label = "EdgesFaces"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "Edge/Face Select"
+
+ def execute(self, context):
+ if context.object.mode != "EDIT":
+ bpy.ops.object.mode_set(mode="EDIT")
+ context.tool_settings.mesh_select_mode = (False, True, True)
+ if context.object.mode == "EDIT":
+ context.tool_settings.mesh_select_mode = (False, True, True)
+ return {'FINISHED'}
+
+
+class VertsFaces(Operator):
+ bl_idname = "verts.faces"
+ bl_label = "Verts Faces"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "Vert/Face Select"
+
+ def execute(self, context):
+ if context.object.mode != "EDIT":
+ bpy.ops.object.mode_set(mode="EDIT")
+ context.tool_settings.mesh_select_mode = (True, False, True)
+ if context.object.mode == "EDIT":
+ context.tool_settings.mesh_select_mode = (True, False, True)
+ return {'FINISHED'}
+
+
+class VertsEdgesFaces(Operator):
+ bl_idname = "verts.edgesfaces"
+ bl_label = "Verts Edges Faces"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "Vert/Edge/Face Select"
+
+ def execute(self, context):
+ if context.object.mode != "EDIT":
+ bpy.ops.object.mode_set(mode="EDIT")
+ context.tool_settings.mesh_select_mode = (True, True, True)
+ if context.object.mode == "EDIT":
+ context.tool_settings.mesh_select_mode = (True, True, True)
+ return {'FINISHED'}
+
+# Pie Edit/Object Others modes - Tab
+
+
+class PieObjectEditotherModes(Menu):
+ bl_idname = "pie.objecteditmodeothermodes"
+ bl_label = "Edit Selection Modes"
+
+ def draw(self, context):
+ layout = self.layout
+ pie = layout.menu_pie()
+ # 4 - LEFT
+ pie.operator("verts.faces", text="Vertex/Faces", icon='LOOPSEL')
+ # 6 - RIGHT
+ pie.operator("edges.faces", text="Edges/Faces", icon='FACESEL')
+ # 2 - BOTTOM
+ pie.operator("wm.context_toggle", text="Limit to Visible",
+ icon="ORTHO").data_path = "space_data.use_occlude_geometry"
+ # 8 - TOP
+ pie.operator("class.edge", text="Edge", icon='EDGESEL')
+ # 7 - TOP - LEFT
+ pie.operator("class.vertex", text="Vertex", icon='VERTEXSEL')
+ # 9 - TOP - RIGHT
+ pie.operator("class.face", text="Face", icon='FACESEL')
+ # 1 - BOTTOM - LEFT
+ pie.operator("verts.edges", text="Vertex/Edges", icon='VERTEXSEL')
+ # 3 - BOTTOM - RIGHT
+ pie.operator("verts.edgesfaces", text="Vertex/Edges/Faces", icon='OBJECT_DATAMODE')
+
+# Pie Modes Switch- Tab key
+
+
+class PieObjectEditMode(Menu):
+ bl_idname = "pie.objecteditmode"
+ bl_label = "Modes Menu (Tab)"
+
+ def draw(self, context):
+ layout = self.layout
+ ob = context.object
+
+ if ob and ob.type == 'MESH' and ob.mode in {'OBJECT', 'SCULPT', 'VERTEX_PAINT', 'WEIGHT_PAINT', 'TEXTURE_PAINT', 'PARTICLE'}:
+ pie = layout.menu_pie()
+ # 4 - LEFT
+ pie.operator("class.pievertexpaint", text="Vertex Paint", icon='VPAINT_HLT')
+ # 6 - RIGHT
+ pie.operator("class.pietexturepaint", text="Texture Paint", icon='TPAINT_HLT')
+ # 2 - BOTTOM
+ pie.operator("class.pieweightpaint", text="Weight Paint", icon='WPAINT_HLT')
+ # 8 - TOP
+ pie.operator("class.object", text="Edit/Object Toggle", icon='OBJECT_DATAMODE')
+ # 7 - TOP - LEFT
+ pie.operator("sculpt.sculptmode_toggle", text="Sculpt", icon='SCULPTMODE_HLT')
+ # 9 - TOP - RIGHT
+ pie.operator("wm.call_menu_pie", text="Edit Modes",
+ icon='EDITMODE_HLT').name = "pie.objecteditmodeothermodes"
+ # 1 - BOTTOM - LEFT
+ if context.object.particle_systems:
+ pie.operator("class.pieparticleedit", text="Particle Edit", icon='PARTICLEMODE')
+ # 3 - BOTTOM - RIGHT
+
+ if ob and ob.type == 'MESH' and ob.mode in {'EDIT'}:
+ pie = layout.menu_pie()
+ # 4 - LEFT
+ pie.operator("class.pievertexpaint", text="Vertex Paint", icon='VPAINT_HLT')
+ # 6 - RIGHT
+ pie.operator("class.pietexturepaint", text="Texture Paint", icon='TPAINT_HLT')
+ # 2 - BOTTOM
+ pie.operator("class.pieweightpaint", text="Weight Paint", icon='WPAINT_HLT')
+ # 8 - TOP
+ pie.operator("class.object", text="Edit/Object Toggle", icon='OBJECT_DATAMODE')
+ # 7 - TOP - LEFT
+ pie.operator("sculpt.sculptmode_toggle", text="Sculpt", icon='SCULPTMODE_HLT')
+ # 9 - TOP - RIGHT
+ pie.operator("wm.call_menu_pie", text="Edit Modes",
+ icon='TPAINT_HLT').name = "pie.objecteditmodeothermodes"
+ # 1 - BOTTOM - LEFT
+ if context.object.particle_systems:
+ pie.operator("class.pieparticleedit", text="Particle Edit", icon='PARTICLEMODE')
+ # 3 - BOTTOM - RIGHT
+
+ if ob and ob.type == 'CURVE':
+ pie = layout.menu_pie()
+ pie.operator("object.editmode_toggle", text="Edit/Object", icon='OBJECT_DATAMODE')
+
+ if ob and ob.type == 'ARMATURE':
+ pie = layout.menu_pie()
+ pie.operator("object.editmode_toggle", text="Edit Mode", icon='OBJECT_DATAMODE')
+ pie.operator("object.posemode_toggle", text="Pose", icon='POSE_HLT')
+ pie.operator("class.object", text="Object Mode", icon='OBJECT_DATAMODE')
+
+ if ob and ob.type == 'FONT':
+ pie = layout.menu_pie()
+ pie.operator("object.editmode_toggle", text="Edit/Object Toggle", icon='OBJECT_DATAMODE')
+
+ if ob and ob.type == 'SURFACE':
+ pie = layout.menu_pie()
+ pie.operator("object.editmode_toggle", text="Edit/Object Toggle", icon='OBJECT_DATAMODE')
+
+ if ob and ob.type == 'META':
+ pie = layout.menu_pie()
+ pie.operator("object.editmode_toggle", text="Edit/Object Toggle", icon='OBJECT_DATAMODE')
+
+ if ob and ob.type == 'LATTICE':
+ pie = layout.menu_pie()
+ pie.operator("object.editmode_toggle", text="Edit/Object Toggle", icon='OBJECT_DATAMODE')
+
+classes = (
+ PieObjectEditMode,
+ ClassObject,
+ ClassVertex,
+ ClassEdge,
+ ClassFace,
+ PieObjectEditotherModes,
+ ClassTexturePaint,
+ ClassWeightPaint,
+ ClassVertexPaint,
+ ClassParticleEdit,
+ VertsEdges,
+ EdgesFaces,
+ VertsFaces,
+ VertsEdgesFaces
+ )
+
+addon_keymaps = []
+
+
+def register():
+ for cls in classes:
+ bpy.utils.register_class(cls)
+ wm = bpy.context.window_manager
+
+ if wm.keyconfigs.addon:
+ # Select Mode
+ km = wm.keyconfigs.addon.keymaps.new(name='Object Non-modal')
+ kmi = km.keymap_items.new('wm.call_menu_pie', 'TAB', 'PRESS')
+ kmi.properties.name = "pie.objecteditmode"
+# kmi.active = True
+ addon_keymaps.append((km, kmi))
+
+
+def unregister():
+ for cls in classes:
+ bpy.utils.unregister_class(cls)
+ wm = bpy.context.window_manager
+
+ kc = wm.keyconfigs.addon
+ if kc:
+ km = kc.keymaps['Object Non-modal']
+ for kmi in km.keymap_items:
+ if kmi.idname == 'wm.call_menu_pie':
+ if kmi.properties.name == "pie.objecteditmode":
+ km.keymap_items.remove(kmi)
+
+if __name__ == "__main__":
+ register()
diff --git a/space_view3d_pie_menus/pie_orientation_menu/__init__.py b/space_view3d_pie_menus/pie_orientation_menu/__init__.py
new file mode 100644
index 00000000..17c13a5c
--- /dev/null
+++ b/space_view3d_pie_menus/pie_orientation_menu/__init__.py
@@ -0,0 +1,117 @@
+# ##### 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>
+
+"""Replace default list-style menu for transform orientations with a pie."""
+
+bl_info = {
+ "name": "Hotkey: 'Alt + Spacebar'",
+ # "author": "Italic_",
+ # "version": (1, 1, 0),
+ "blender": (2, 77, 0),
+ "description": "Set Transform Orientations",
+ "location": "3D View",
+ "category": "Orientation Pie"}
+
+import bpy
+from bpy.types import (
+ Menu,
+ Operator,
+ )
+from bpy.props import (
+ StringProperty,
+ )
+
+class OrientPoll(Operator):
+ bl_idname = "pie.orientation"
+ bl_label = "Orientation Poll"
+ bl_options = {'INTERNAL'}
+
+ space = bpy.props.StringProperty()
+
+ @classmethod
+ def poll(cls, context):
+ return context.space_data.type == "VIEW_3D"
+
+ def execute(self, context):
+ context.space_data.transform_orientation = self.space
+ return {'FINISHED'}
+
+
+class OrientPie(Menu):
+ bl_label = "Transform Orientation"
+ bl_idname = "pie.orient"
+
+ def draw(self, context):
+ layout = self.layout
+ pie = layout.menu_pie()
+ view = context.space_data
+
+ pie.operator("pie.orientation", text="Global").space = 'GLOBAL'
+ pie.operator("pie.orientation", text="Local").space = 'LOCAL'
+ pie.operator("pie.orientation", text="Gimbal").space = 'GIMBAL'
+
+ # XXX: Display only custom orientations
+ pie = pie.box()
+ pie.prop(view, "transform_orientation", text="")
+ pie = layout.menu_pie()
+
+ pie.operator("pie.orientation", text="Normal").space = 'NORMAL'
+ pie.operator("pie.orientation", text="View").space = 'VIEW'
+
+
+addon_keymaps = []
+
+classes = (
+ OrientPie,
+ OrientPoll
+ )
+
+
+def register():
+ for cls in classes:
+ bpy.utils.register_class(cls)
+
+ wm = bpy.context.window_manager
+
+ if wm.keyconfigs.addon:
+ # Manipulators
+ km = wm.keyconfigs.addon.keymaps.new(name='3D View Generic', space_type='VIEW_3D')
+ kmi = km.keymap_items.new('wm.call_menu_pie', 'SPACE', 'PRESS', alt=True)
+ kmi.properties.name = "pie.orient"
+# kmi.active = True
+ addon_keymaps.append((km, kmi))
+
+
+def unregister():
+ for cls in classes:
+ bpy.utils.unregister_class(cls)
+
+ wm = bpy.context.window_manager
+ kc = wm.keyconfigs.addon
+ if kc:
+ km = kc.keymaps['3D View Generic']
+ for kmi in km.keymap_items:
+ if kmi.idname == 'wm.call_menu_pie':
+ if kmi.properties.name == "pie.orient":
+ km.keymap_items.remove(kmi)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/space_view3d_pie_menus/pie_origin_cursor/__init__.py b/space_view3d_pie_menus/pie_origin_cursor/__init__.py
new file mode 100644
index 00000000..553c8a9b
--- /dev/null
+++ b/space_view3d_pie_menus/pie_origin_cursor/__init__.py
@@ -0,0 +1,225 @@
+# ##### 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": "Hotkey: 'Shift S'",
+ "description": "Cursor & Origin Snap/Place Menu",
+ # "author": "pitiwazou, meta-androcto",
+ # "version": (0, 1, 0),
+ "blender": (2, 77, 0),
+ "location": "3D View",
+ "warning": "",
+ "wiki_url": "",
+ "category": "Cursor/Origin Pie"
+ }
+
+import bpy
+from bpy.types import (
+ Menu,
+ Operator,
+ )
+
+# SnapCursSelToCenter1 thanks to Isaac Weaver (wisaac) D1963
+
+
+class SnapCursSelToCenter1(Operator):
+ """Snap 3D cursor and selected objects to the center \n"""\
+ """Works only in Object Mode"""
+ bl_idname = "view3d.snap_cursor_selected_to_center1"
+ bl_label = "Snap Cursor & Selection to Center"
+
+ @classmethod
+ def poll(cls, context):
+ return (context.mode == "OBJECT")
+
+ def execute(self, context):
+ context.space_data.cursor_location = (0, 0, 0)
+ for obj in context.selected_objects:
+ obj.location = (0, 0, 0)
+ return {'FINISHED'}
+
+# Pivot to selection
+
+
+class PivotToSelection(Operator):
+ bl_idname = "object.pivot2selection"
+ bl_label = "Pivot To Selection"
+ bl_description = "Pivot Point To Selection"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ saved_location = context.scene.cursor_location.copy()
+ bpy.ops.view3d.snap_cursor_to_selected()
+ bpy.ops.object.mode_set(mode='OBJECT')
+ bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
+ context.scene.cursor_location = saved_location
+ return {'FINISHED'}
+
+# Pivot to Bottom
+
+
+class PivotBottom(Operator):
+ bl_idname = "object.pivotobottom"
+ bl_label = "Pivot To Bottom"
+ bl_description = "Set the Pivot Point To Lowest Point"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
+ bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
+ o = context.active_object
+ init = 0
+ for x in o.data.vertices:
+ if init == 0:
+ a = x.co.z
+ init = 1
+ elif x.co.z < a:
+ a = x.co.z
+
+ for x in o.data.vertices:
+ x.co.z -= a
+
+ o.location.z += a
+ bpy.ops.object.mode_set(mode='EDIT')
+ return {'FINISHED'}
+
+# Pie Origin/Pivot - Shift + S
+
+
+class PieOriginPivot(Menu):
+ bl_idname = "pie.originpivot"
+ bl_label = "Origin Menu"
+
+ def draw(self, context):
+ layout = self.layout
+ obj = context.object
+ pie = layout.menu_pie()
+ if obj and obj.type == 'MESH':
+ # 4 - LEFT
+ pie.operator("object.origin_set", text="Origin to Center of Mass",
+ icon='BBOX').type = 'ORIGIN_CENTER_OF_MASS'
+ # 6 - RIGHT
+ pie.operator("object.origin_set", text="Origin To 3D Cursor", icon='CURSOR').type = 'ORIGIN_CURSOR'
+ # 2 - BOTTOM
+ pie.operator("object.pivotobottom", text="Origin to Bottom", icon='TRIA_DOWN')
+ # 8 - TOP
+ pie.operator("object.pivot2selection", text="Origin To Selection", icon='SNAP_INCREMENT')
+ # 7 - TOP - LEFT
+ pie.operator("object.origin_set", text="Geometry To Origin", icon='BBOX').type = 'GEOMETRY_ORIGIN'
+ # 9 - TOP - RIGHT
+ pie.operator("object.origin_set", text="Origin To Geometry", icon='ROTATE').type = 'ORIGIN_GEOMETRY'
+
+ else:
+ # 4 - LEFT
+ pie.operator("object.origin_set", text="Origin to Center of Mass",
+ icon='BBOX').type = 'ORIGIN_CENTER_OF_MASS'
+ # 6 - RIGHT
+ pie.operator("object.origin_set", text="Origin To 3D Cursor", icon='CURSOR').type = 'ORIGIN_CURSOR'
+ # 2 - BOTTOM
+ pie.operator("object.pivot2selection", text="Origin To Selection", icon='SNAP_INCREMENT')
+ # 8 - TOP
+ pie.operator("object.origin_set", text="Origin To Geometry", icon='ROTATE').type = 'ORIGIN_GEOMETRY'
+ # 7 - TOP - LEFT
+ pie.operator("object.origin_set", text="Geometry To Origin", icon='BBOX').type = 'GEOMETRY_ORIGIN'
+
+
+# Origin/Pivot menu1 - Shift + S
+class OriginPivotMenu(Menu):
+ bl_idname = "origin.pivotmenu"
+ bl_label = "Cursor Menu"
+
+ def draw(self, context):
+ layout = self.layout
+ pie = layout.menu_pie()
+ # 4 - LEFT
+ pie.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor",
+ icon='CLIPUV_HLT').use_offset = False
+ # 6 - RIGHT
+ pie.operator("view3d.snap_selected_to_cursor",
+ text="Selection to Cursor (Offset)", icon='CURSOR').use_offset = True
+ # 2 - BOTTOM
+ pie.operator("wm.call_menu_pie", text="Origin Pie", icon='ROTATECOLLECTION').name = "pie.originpivot"
+ # 8 - TOP
+ pie.operator("view3d.snap_cursor_to_center", text="Cursor to Center", icon='CLIPUV_DEHLT')
+ # 7 - TOP - LEFT
+ pie.operator("view3d.snap_cursor_to_selected", text="Cursor to Selected", icon='ROTACTIVE')
+ # 9 - TOP - RIGHT
+ pie.operator("view3d.snap_cursor_to_active", text="Cursor to Active", icon='BBOX')
+ # 1 - BOTTOM - LEFT
+ pie.operator("view3d.snap_cursor_selected_to_center1", text="Selected & Cursor to Center", icon='ALIGN')
+ # 3 - BOTTOM - RIGHT
+ pie.menu("snapgrid.menu", text="Snap Grid", icon='GRID')
+
+# More Menu
+
+
+class Snap_CursorGrid(Menu):
+ bl_idname = "snapgrid.menu"
+ bl_label = "More Menu"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator("view3d.snap_selected_to_grid", text="Selection to Grid", icon='GRID')
+ layout.operator("view3d.snap_cursor_to_grid", text="Cursor to Grid", icon='GRID')
+
+classes = (
+ OriginPivotMenu,
+ PieOriginPivot,
+ PivotToSelection,
+ PivotBottom,
+ SnapCursSelToCenter1,
+ Snap_CursorGrid,
+ )
+
+addon_keymaps = []
+
+
+def register():
+ for cls in classes:
+ bpy.utils.register_class(cls)
+ wm = bpy.context.window_manager
+
+ if wm.keyconfigs.addon:
+ # Origin/Pivot
+ km = wm.keyconfigs.addon.keymaps.new(name='3D View Generic', space_type='VIEW_3D')
+ kmi = km.keymap_items.new('wm.call_menu_pie', 'S', 'PRESS', shift=True)
+ kmi.properties.name = "origin.pivotmenu"
+# kmi.active = True
+ addon_keymaps.append((km, kmi))
+
+
+def unregister():
+ for cls in classes:
+ bpy.utils.unregister_class(cls)
+ wm = bpy.context.window_manager
+
+ kc = wm.keyconfigs.addon
+ if kc:
+ km = kc.keymaps['3D View Generic']
+ for kmi in km.keymap_items:
+ if kmi.idname == 'wm.call_menu_pie':
+ if kmi.properties.name == "origin.pivotmenu":
+ km.keymap_items.remove(kmi)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/space_view3d_pie_menus/pie_pivot_point_menu/__init__.py b/space_view3d_pie_menus/pie_pivot_point_menu/__init__.py
new file mode 100644
index 00000000..b58d33f8
--- /dev/null
+++ b/space_view3d_pie_menus/pie_pivot_point_menu/__init__.py
@@ -0,0 +1,85 @@
+# ##### 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": "Hotkey: ' . key' ",
+ "description": "Set Pivot Point Menu",
+ # "author": "seb_k, meta-androcto",
+ # "version": (0, 1, 0),
+ "blender": (2, 77, 0),
+ "location": "3D View",
+ "warning": "",
+ "wiki_url": "",
+ "category": "Pivot Point Pie"
+ }
+
+import bpy
+from bpy.types import Menu
+
+
+class VIEW3D_PIE_pivot(Menu):
+ bl_label = "Pivot"
+ bl_idname = "pie.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")
+
+
+classes = (
+ VIEW3D_PIE_pivot,
+ )
+
+addon_keymaps = []
+
+
+def register():
+ for cls in classes:
+ bpy.utils.register_class(cls)
+ wm = bpy.context.window_manager
+
+ if wm.keyconfigs.addon:
+ # Pivot Point
+ km = wm.keyconfigs.addon.keymaps.new(name='3D View Generic', space_type='VIEW_3D')
+ kmi = km.keymap_items.new('wm.call_menu_pie', 'PERIOD', 'PRESS')
+ kmi.properties.name = "pie.pivot"
+# kmi.active = True
+ addon_keymaps.append((km, kmi))
+
+
+def unregister():
+ for cls in classes:
+ bpy.utils.unregister_class(cls)
+ wm = bpy.context.window_manager
+
+ kc = wm.keyconfigs.addon
+ if kc:
+ km = kc.keymaps['3D View Generic']
+ for kmi in km.keymap_items:
+ if kmi.idname == 'wm.call_menu_pie':
+ if kmi.properties.name == "pie.pivot":
+ km.keymap_items.remove(kmi)
+
+if __name__ == "__main__":
+ register()
diff --git a/space_view3d_pie_menus/pie_proportional_menu/__init__.py b/space_view3d_pie_menus/pie_proportional_menu/__init__.py
new file mode 100644
index 00000000..ea5ddeed
--- /dev/null
+++ b/space_view3d_pie_menus/pie_proportional_menu/__init__.py
@@ -0,0 +1,468 @@
+# ##### 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": "Hotkey: 'O'",
+ "description": "Proportional Object/Edit Tools",
+ # "author": "pitiwazou, meta-androcto",
+ # "version": (0, 1, 0),
+ "blender": (2, 77, 0),
+ "location": "3D View Object & Edit modes",
+ "warning": "",
+ "wiki_url": "",
+ "category": "Proportional Edit Pie"
+ }
+
+import bpy
+from bpy.types import (
+ Menu,
+ Operator,
+ )
+
+#####################################
+# Proportional Edit Object #
+#####################################
+
+
+class ProportionalEditObj(Operator):
+ bl_idname = "proportional_obj.active"
+ bl_label = "Proportional Edit Object"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+
+ if ts.use_proportional_edit_objects == True:
+ ts.use_proportional_edit_objects = False
+
+ elif ts.use_proportional_edit_objects == False:
+ ts.use_proportional_edit_objects = True
+
+ return {'FINISHED'}
+
+
+class ProportionalSmoothObj(Operator):
+ bl_idname = "proportional_obj.smooth"
+ bl_label = "Proportional Smooth Object"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+ if ts.use_proportional_edit_objects == False:
+ ts.use_proportional_edit_objects = True
+ ts.proportional_edit_falloff = 'SMOOTH'
+
+ if ts.proportional_edit_falloff != 'SMOOTH':
+ ts.proportional_edit_falloff = 'SMOOTH'
+ return {'FINISHED'}
+
+
+class ProportionalSphereObj(Operator):
+ bl_idname = "proportional_obj.sphere"
+ bl_label = "Proportional Sphere Object"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+ if ts.use_proportional_edit_objects == False:
+ ts.use_proportional_edit_objects = True
+ ts.proportional_edit_falloff = 'SPHERE'
+
+ if ts.proportional_edit_falloff != 'SPHERE':
+ ts.proportional_edit_falloff = 'SPHERE'
+ return {'FINISHED'}
+
+
+class ProportionalRootObj(Operator):
+ bl_idname = "proportional_obj.root"
+ bl_label = "Proportional Root Object"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+ if ts.use_proportional_edit_objects == False:
+ ts.use_proportional_edit_objects = True
+ ts.proportional_edit_falloff = 'ROOT'
+
+ if ts.proportional_edit_falloff != 'ROOT':
+ ts.proportional_edit_falloff = 'ROOT'
+ return {'FINISHED'}
+
+
+class ProportionalSharpObj(Operator):
+ bl_idname = "proportional_obj.sharp"
+ bl_label = "Proportional Sharp Object"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+ if ts.use_proportional_edit_objects == False:
+ ts.use_proportional_edit_objects = True
+ ts.proportional_edit_falloff = 'SHARP'
+
+ if ts.proportional_edit_falloff != 'SHARP':
+ ts.proportional_edit_falloff = 'SHARP'
+ return {'FINISHED'}
+
+
+class ProportionalLinearObj(Operator):
+ bl_idname = "proportional_obj.linear"
+ bl_label = "Proportional Linear Object"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+ if ts.use_proportional_edit_objects == False:
+ ts.use_proportional_edit_objects = True
+ ts.proportional_edit_falloff = 'LINEAR'
+
+ if ts.proportional_edit_falloff != 'LINEAR':
+ ts.proportional_edit_falloff = 'LINEAR'
+ return {'FINISHED'}
+
+
+class ProportionalConstantObj(Operator):
+ bl_idname = "proportional_obj.constant"
+ bl_label = "Proportional Constant Object"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+ if ts.use_proportional_edit_objects == False:
+ ts.use_proportional_edit_objects = True
+ ts.proportional_edit_falloff = 'CONSTANT'
+
+ if ts.proportional_edit_falloff != 'CONSTANT':
+ ts.proportional_edit_falloff = 'CONSTANT'
+ return {'FINISHED'}
+
+
+class ProportionalRandomObj(Operator):
+ bl_idname = "proportional_obj.random"
+ bl_label = "Proportional Random Object"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+ if ts.use_proportional_edit_objects == False:
+ ts.use_proportional_edit_objects = True
+ ts.proportional_edit_falloff = 'RANDOM'
+
+ if ts.proportional_edit_falloff != 'RANDOM':
+ ts.proportional_edit_falloff = 'RANDOM'
+ return {'FINISHED'}
+
+#######################################
+# Proportional Edit Edit Mode #
+#######################################
+
+
+class ProportionalEditEdt(Operator):
+ bl_idname = "proportional_edt.active"
+ bl_label = "Proportional Edit EditMode"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+
+ if ts.proportional_edit != ('DISABLED'):
+ ts.proportional_edit = 'DISABLED'
+ elif ts.proportional_edit != ('ENABLED'):
+ ts.proportional_edit = 'ENABLED'
+ return {'FINISHED'}
+
+
+class ProportionalConnectedEdt(Operator):
+ bl_idname = "proportional_edt.connected"
+ bl_label = "Proportional Connected EditMode"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+ if ts.proportional_edit != ('CONNECTED'):
+ ts.proportional_edit = 'CONNECTED'
+ return {'FINISHED'}
+
+
+class ProportionalProjectedEdt(Operator):
+ bl_idname = "proportional_edt.projected"
+ bl_label = "Proportional projected EditMode"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+
+ if ts.proportional_edit != ('PROJECTED'):
+ ts.proportional_edit = 'PROJECTED'
+ return {'FINISHED'}
+
+
+class ProportionalSmoothEdt(Operator):
+ bl_idname = "proportional_edt.smooth"
+ bl_label = "Proportional Smooth EditMode"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+ if ts.proportional_edit == 'DISABLED':
+ ts.proportional_edit = 'ENABLED'
+ ts.proportional_edit_falloff = 'SMOOTH'
+
+ if ts.proportional_edit_falloff != 'SMOOTH':
+ ts.proportional_edit_falloff = 'SMOOTH'
+ return {'FINISHED'}
+
+
+class ProportionalSphereEdt(Operator):
+ bl_idname = "proportional_edt.sphere"
+ bl_label = "Proportional Sphere EditMode"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+ if ts.proportional_edit == 'DISABLED':
+ ts.proportional_edit = 'ENABLED'
+ ts.proportional_edit_falloff = 'SPHERE'
+
+ if ts.proportional_edit_falloff != 'SPHERE':
+ ts.proportional_edit_falloff = 'SPHERE'
+ return {'FINISHED'}
+
+
+class ProportionalRootEdt(Operator):
+ bl_idname = "proportional_edt.root"
+ bl_label = "Proportional Root EditMode"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+ if ts.proportional_edit == 'DISABLED':
+ ts.proportional_edit = 'ENABLED'
+ ts.proportional_edit_falloff = 'ROOT'
+
+ if ts.proportional_edit_falloff != 'ROOT':
+ ts.proportional_edit_falloff = 'ROOT'
+ return {'FINISHED'}
+
+
+class ProportionalSharpEdt(Operator):
+ bl_idname = "proportional_edt.sharp"
+ bl_label = "Proportional Sharp EditMode"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+ if ts.proportional_edit == 'DISABLED':
+ ts.proportional_edit = 'ENABLED'
+ ts.proportional_edit_falloff = 'SHARP'
+
+ if ts.proportional_edit_falloff != 'SHARP':
+ ts.proportional_edit_falloff = 'SHARP'
+ return {'FINISHED'}
+
+
+class ProportionalLinearEdt(Operator):
+ bl_idname = "proportional_edt.linear"
+ bl_label = "Proportional Linear EditMode"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+ if ts.proportional_edit == 'DISABLED':
+ ts.proportional_edit = 'ENABLED'
+ ts.proportional_edit_falloff = 'LINEAR'
+
+ if ts.proportional_edit_falloff != 'LINEAR':
+ ts.proportional_edit_falloff = 'LINEAR'
+ return {'FINISHED'}
+
+
+class ProportionalConstantEdt(Operator):
+ bl_idname = "proportional_edt.constant"
+ bl_label = "Proportional Constant EditMode"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+ if ts.proportional_edit == 'DISABLED':
+ ts.proportional_edit = 'ENABLED'
+ ts.proportional_edit_falloff = 'CONSTANT'
+
+ if ts.proportional_edit_falloff != 'CONSTANT':
+ ts.proportional_edit_falloff = 'CONSTANT'
+ return {'FINISHED'}
+
+
+class ProportionalRandomEdt(Operator):
+ bl_idname = "proportional_edt.random"
+ bl_label = "Proportional Random EditMode"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+ if ts.proportional_edit == 'DISABLED':
+ ts.proportional_edit = 'ENABLED'
+ ts.proportional_edit_falloff = 'RANDOM'
+
+ if ts.proportional_edit_falloff != 'RANDOM':
+ ts.proportional_edit_falloff = 'RANDOM'
+ return {'FINISHED'}
+
+# Pie ProportionalEditObj - O
+
+
+class PieProportionalObj(Menu):
+ bl_idname = "pie.proportional_obj"
+ bl_label = "Pie Proportional Obj"
+
+ def draw(self, context):
+ layout = self.layout
+ pie = layout.menu_pie()
+ # 4 - LEFT
+ pie.operator("proportional_obj.sphere", text="Sphere", icon='SPHERECURVE')
+ # 6 - RIGHT
+ pie.operator("proportional_obj.root", text="Root", icon='ROOTCURVE')
+ # 2 - BOTTOM
+ pie.operator("proportional_obj.smooth", text="Smooth", icon='SMOOTHCURVE')
+ # 8 - TOP
+ pie.prop(context.tool_settings, "use_proportional_edit_objects", text="Proportional On/Off")
+ # 7 - TOP - LEFT
+ pie.operator("proportional_obj.linear", text="Linear", icon='LINCURVE')
+ # 9 - TOP - RIGHT
+ pie.operator("proportional_obj.sharp", text="Sharp", icon='SHARPCURVE')
+ # 1 - BOTTOM - LEFT
+ pie.operator("proportional_obj.constant", text="Constant", icon='NOCURVE')
+ # 3 - BOTTOM - RIGHT
+ pie.operator("proportional_obj.random", text="Random", icon='RNDCURVE')
+
+# Pie ProportionalEditEdt - O
+
+
+class PieProportionalEdt(Menu):
+ bl_idname = "pie.proportional_edt"
+ bl_label = "Pie Proportional Edit"
+
+ def draw(self, context):
+ layout = self.layout
+ pie = layout.menu_pie()
+ # 4 - LEFT
+ pie.operator("proportional_edt.connected", text="Connected", icon='PROP_CON')
+ # 6 - RIGHT
+ pie.operator("proportional_edt.projected", text="Projected", icon='PROP_ON')
+ # 2 - BOTTOM
+ pie.operator("proportional_edt.smooth", text="Smooth", icon='SMOOTHCURVE')
+ # 8 - TOP
+ pie.operator("proportional_edt.active", text="Proportional On/Off", icon='PROP_ON')
+ # 7 - TOP - LEFT
+ pie.operator("proportional_edt.sphere", text="Sphere", icon='SPHERECURVE')
+ # 9 - TOP - RIGHT
+ pie.operator("proportional_edt.root", text="Root", icon='ROOTCURVE')
+ # 1 - BOTTOM - LEFT
+ pie.operator("proportional_edt.constant", text="Constant", icon='NOCURVE')
+ # 3 - BOTTOM - RIGHT
+ pie.menu("pie.proportional_more", text="More", icon='LINCURVE')
+
+# Pie ProportionalEditEdt - O
+
+
+class PieProportionalMore(Menu):
+ bl_idname = "pie.proportional_more"
+ bl_label = "Pie Proportional More"
+
+ def draw(self, context):
+ layout = self.layout
+ pie = layout.menu_pie()
+ box = pie.split().column()
+ row = box.row(align=True)
+ box.operator("proportional_edt.linear", text="Linear", icon='LINCURVE')
+ box.operator("proportional_edt.sharp", text="Sharp", icon='SHARPCURVE')
+ box.operator("proportional_edt.random", text="Random", icon='RNDCURVE')
+
+classes = (
+ ProportionalEditObj,
+ ProportionalSmoothObj,
+ ProportionalSphereObj,
+ ProportionalRootObj,
+ ProportionalSharpObj,
+ ProportionalLinearObj,
+ ProportionalConstantObj,
+ ProportionalRandomObj,
+ ProportionalEditEdt,
+ ProportionalConnectedEdt,
+ ProportionalProjectedEdt,
+ ProportionalSmoothEdt,
+ ProportionalSphereEdt,
+ ProportionalRootEdt,
+ ProportionalSharpEdt,
+ ProportionalLinearEdt,
+ ProportionalConstantEdt,
+ ProportionalRandomEdt,
+ PieProportionalObj,
+ PieProportionalEdt,
+ PieProportionalMore,
+ )
+
+addon_keymaps = []
+
+
+def register():
+ for cls in classes:
+ bpy.utils.register_class(cls)
+ wm = bpy.context.window_manager
+
+ if wm.keyconfigs.addon:
+ # ProportionalEditObj
+ km = wm.keyconfigs.addon.keymaps.new(name='Object Mode')
+ kmi = km.keymap_items.new('wm.call_menu_pie', 'O', 'PRESS')
+ kmi.properties.name = "pie.proportional_obj"
+# kmi.active = True
+ addon_keymaps.append((km, kmi))
+
+ # ProportionalEditEdt
+ km = wm.keyconfigs.addon.keymaps.new(name='Mesh')
+ kmi = km.keymap_items.new('wm.call_menu_pie', 'O', 'PRESS')
+ kmi.properties.name = "pie.proportional_edt"
+# kmi.active = True
+ addon_keymaps.append((km, kmi))
+
+
+def unregister():
+ for cls in classes:
+ bpy.utils.unregister_class(cls)
+ wm = bpy.context.window_manager
+
+ kc = wm.keyconfigs.addon
+ if kc:
+ km = kc.keymaps['Object Mode']
+ for kmi in km.keymap_items:
+ if kmi.idname == 'wm.call_menu_pie':
+ if kmi.properties.name == "pie.proportional_obj":
+ km.keymap_items.remove(kmi)
+
+ kc = wm.keyconfigs.addon
+ if kc:
+ km = kc.keymaps['Mesh']
+ for kmi in km.keymap_items:
+ if kmi.idname == 'wm.call_menu_pie':
+ if kmi.properties.name == "pie.proportional_edt":
+ km.keymap_items.remove(kmi)
+
+if __name__ == "__main__":
+ register()
diff --git a/space_view3d_pie_menus/pie_save_open_menu/__init__.py b/space_view3d_pie_menus/pie_save_open_menu/__init__.py
new file mode 100644
index 00000000..2b8e4e87
--- /dev/null
+++ b/space_view3d_pie_menus/pie_save_open_menu/__init__.py
@@ -0,0 +1,217 @@
+# ##### 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": "Hotkey: 'Ctrl S'",
+ "description": "Save/Open & File Menus",
+ "blender": (2, 77, 0),
+ "location": "All Editors",
+ "warning": "",
+ "wiki_url": "",
+ "category": "Save Open Pie"
+ }
+
+import bpy
+from bpy.types import (
+ Menu,
+ Operator,
+ )
+import os
+
+# Pie Save/Open
+
+
+class PieSaveOpen(Menu):
+ bl_idname = "pie.saveopen"
+ bl_label = "Pie Save/Open"
+
+ def draw(self, context):
+ layout = self.layout
+ pie = layout.menu_pie()
+ # 4 - LEFT
+ pie.operator("wm.read_homefile", text="New", icon='NEW')
+ # 6 - RIGHT
+ pie.menu("pie.link", text="Link", icon='LINK_BLEND')
+ # 2 - BOTTOM
+ pie.menu("pie.fileio", text="Import/Export", icon='IMPORT')
+ # 8 - TOP
+ pie.operator("file.save_incremental", text="Incremental Save", icon='SAVE_COPY')
+ # 7 - TOP - LEFT
+ pie.operator("wm.save_mainfile", text="Save", icon='FILE_TICK')
+ # 9 - TOP - RIGHT
+ pie.operator("wm.save_as_mainfile", text="Save As...", icon='SAVE_AS')
+ # 1 - BOTTOM - LEFT
+ pie.operator("wm.open_mainfile", text="Open file", icon='FILE_FOLDER')
+ # 3 - BOTTOM - RIGHT
+ pie.menu("pie.recover", text="Recovery", icon='RECOVER_LAST')
+
+
+class pie_link(Menu):
+ bl_idname = "pie.link"
+ bl_label = "Link"
+
+ def draw(self, context):
+ layout = self.layout
+ pie = layout.menu_pie()
+ box = pie.split().column()
+ row = box.row(align=True)
+ box.operator("wm.link", text="Link", icon='LINK_BLEND')
+ box.operator("wm.append", text="Append", icon='APPEND_BLEND')
+ box.menu("external.data", text="External Data", icon='EXTERNAL_DATA')
+
+
+class pie_recover(Menu):
+ bl_idname = "pie.recover"
+ bl_label = "Recovery"
+
+ def draw(self, context):
+ layout = self.layout
+ pie = layout.menu_pie()
+ box = pie.split().column()
+ row = box.row(align=True)
+ box.operator("wm.recover_auto_save", text="Recover Auto Save...", icon='RECOVER_AUTO')
+ box.operator("wm.recover_last_session", text="Recover Last Session", icon='RECOVER_LAST')
+ box.operator("wm.revert_mainfile", text="Revert", icon='FILE_REFRESH')
+
+
+class pie_fileio(Menu):
+ bl_idname = "pie.fileio"
+ bl_label = "Import/Export"
+
+ def draw(self, context):
+ layout = self.layout
+ pie = layout.menu_pie()
+ box = pie.split().column()
+ row = box.row(align=True)
+ box.menu("INFO_MT_file_import", icon='IMPORT')
+ box.separator()
+ box.menu("INFO_MT_file_export", icon='EXPORT')
+
+
+class ExternalData(Menu):
+ bl_idname = "external.data"
+ bl_label = "External Data"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.operator("file.autopack_toggle", text="Automatically Pack Into .blend")
+ layout.separator()
+ layout.operator("file.pack_all", text="Pack All Into .blend")
+ layout.operator("file.unpack_all", text="Unpack All Into Files")
+ layout.separator()
+ layout.operator("file.make_paths_relative", text="Make All Paths Relative")
+ layout.operator("file.make_paths_absolute", text="Make All Paths Absolute")
+ layout.operator("file.report_missing_files", text="Report Missing Files")
+ layout.operator("file.find_missing_files", text="Find Missing Files")
+
+
+# Save Incremental
+
+class FileIncrementalSave(Operator):
+ bl_idname = "file.save_incremental"
+ bl_label = "Save Incremental"
+ bl_description = "Save First!then Incremental, .blend will get _001 extension"
+ bl_options = {"REGISTER"}
+
+ @classmethod
+ def poll(cls, context):
+ return (bpy.data.filepath is not "")
+
+ def execute(self, context):
+ f_path = bpy.data.filepath
+ b_name = bpy.path.basename(f_path)
+
+ if b_name and b_name.find("_") != -1:
+ # except in cases when there is an underscore in the name like my_file.blend
+ try:
+ str_nb = b_name.rpartition("_")[-1].rpartition(".blend")[0]
+ int_nb = int(str(str_nb))
+ new_nb = str_nb.replace(str(int_nb), str(int_nb + 1))
+ output = f_path.replace(str_nb, new_nb)
+
+ i = 1
+ while os.path.isfile(output):
+ str_nb = b_name.rpartition("_")[-1].rpartition(".blend")[0]
+ i += 1
+ new_nb = str_nb.replace(str(int_nb), str(int_nb + i))
+ output = f_path.replace(str_nb, new_nb)
+ except ValueError:
+ output = f_path.rpartition(".blend")[0] + "_001" + ".blend"
+ else:
+ # no underscore in the name or saving a nameless (.blend) file
+ output = f_path.rpartition(".blend")[0] + "_001" + ".blend"
+
+ # fix for saving in a directory without privileges
+ try:
+ bpy.ops.wm.save_as_mainfile(filepath=output)
+ except:
+ self.report({'WARNING'}, "File could not be saved. Check the System Console for errors")
+ return {'CANCELLED'}
+
+ self.report(
+ {'INFO'}, "File: {0} - Created at: {1}".format(
+ output[len(bpy.path.abspath("//")):],
+ output[:len(bpy.path.abspath("//"))]),
+ )
+ return {'FINISHED'}
+
+
+classes = (
+ PieSaveOpen,
+ ExternalData,
+ FileIncrementalSave,
+ pie_fileio,
+ pie_recover,
+ pie_link,
+ )
+
+addon_keymaps = []
+
+
+def register():
+ for cls in classes:
+ bpy.utils.register_class(cls)
+ wm = bpy.context.window_manager
+
+ if wm.keyconfigs.addon:
+ # Save/Open/...
+ km = wm.keyconfigs.addon.keymaps.new(name='Window')
+ kmi = km.keymap_items.new('wm.call_menu_pie', 'S', 'PRESS', ctrl=True)
+ kmi.properties.name = "pie.saveopen"
+# kmi.active = True
+ addon_keymaps.append((km, kmi))
+
+
+def unregister():
+ for cls in classes:
+ bpy.utils.unregister_class(cls)
+ wm = bpy.context.window_manager
+
+ kc = wm.keyconfigs.addon
+ if kc:
+ km = kc.keymaps['Window']
+ for kmi in km.keymap_items:
+ if kmi.idname == 'wm.call_menu_pie':
+ if kmi.properties.name == "pie.saveopen":
+ km.keymap_items.remove(kmi)
+
+if __name__ == "__main__":
+ register()
diff --git a/space_view3d_pie_menus/pie_sculpt_menu/__init__.py b/space_view3d_pie_menus/pie_sculpt_menu/__init__.py
new file mode 100644
index 00000000..88b7d501
--- /dev/null
+++ b/space_view3d_pie_menus/pie_sculpt_menu/__init__.py
@@ -0,0 +1,180 @@
+# ##### 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": "Hotkey: 'W' & 'Alt W'",
+ "description": "Sculpt Mode & Brush Menu",
+ # "author": "pitiwazou, meta-androcto",
+ # "version": (0, 1, 0),
+ "blender": (2, 77, 0),
+ "location": "W key & Alt W key",
+ "warning": "",
+ "wiki_url": "",
+ "category": "Sculpt Pie"
+ }
+
+import bpy
+from bpy.types import (
+ Menu,
+ Operator,
+ )
+
+# Sculpt Polish
+
+
+class SculptPolish(Operator):
+ bl_idname = "sculpt.polish"
+ bl_label = "Sculpt Polish"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ context.tool_settings.sculpt.brush = bpy.data.brushes['Polish']
+ return {'FINISHED'}
+
+# Sculpt Polish
+
+
+class SculptSculptDraw(Operator):
+ bl_idname = "sculpt.sculptraw"
+ bl_label = "Sculpt SculptDraw"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ context.tool_settings.sculpt.brush = bpy.data.brushes['SculptDraw']
+ return {'FINISHED'}
+
+# Pie Sculp Pie Menus - W
+
+
+class PieSculptPie(Menu):
+ bl_idname = "pie.sculpt"
+ bl_label = "Pie Sculpt"
+
+ def draw(self, context):
+ layout = self.layout
+ pie = layout.menu_pie()
+ # 4 - LEFT
+ pie.operator("paint.brush_select", text="Crease", icon='BRUSH_CREASE').sculpt_tool = 'CREASE'
+ # 6 - RIGHT
+ pie.operator("paint.brush_select", text="Clay", icon='BRUSH_CLAY').sculpt_tool = 'CLAY'
+ # 2 - BOTTOM
+ pie.operator("wm.call_menu_pie", text="More Brushes", icon='LINE_DATA').name = "pie.sculpttwo"
+ # 8 - TOP
+ pie.operator("paint.brush_select", text='Brush', icon='BRUSH_SCULPT_DRAW').sculpt_tool = 'DRAW'
+ # 7 - TOP - LEFT
+ pie.operator("paint.brush_select", text='Inflate/Deflate', icon='BRUSH_INFLATE').sculpt_tool = 'INFLATE'
+ # 9 - TOP - RIGHT
+ pie.operator("paint.brush_select", text='Grab', icon='BRUSH_GRAB').sculpt_tool = 'GRAB'
+ # 1 - BOTTOM - LEFT
+ pie.operator("paint.brush_select", text='Simplify', icon='BRUSH_DATA').sculpt_tool = 'SIMPLIFY'
+ # 3 - BOTTOM - RIGHT
+ pie.operator("paint.brush_select", text='Flatten', icon='BRUSH_FLATTEN').sculpt_tool = 'FLATTEN'
+
+# Pie Sculp Pie Menus 2 - W
+
+
+class PieSculpttwo(Menu):
+ bl_idname = "pie.sculpttwo"
+ bl_label = "Pie Sculpt 2"
+
+ def draw(self, context):
+ layout = self.layout
+ pie = layout.menu_pie()
+ # 4 - LEFT
+ pie.operator("paint.brush_select", text='Claystrips', icon='BRUSH_CREASE').sculpt_tool = 'CLAY_STRIPS'
+ # 6 - RIGHT
+ pie.operator("paint.brush_select", text='Blob', icon='BRUSH_BLOB').sculpt_tool = 'BLOB'
+ # 2 - BOTTOM
+ pie.operator("paint.brush_select", text='Snakehook', icon='BRUSH_SNAKE_HOOK').sculpt_tool = 'SNAKE_HOOK'
+ # 8 - TOP
+ pie.operator("paint.brush_select", text='Smooth', icon='BRUSH_SMOOTH').sculpt_tool = 'SMOOTH'
+ # 7 - TOP - LEFT
+ pie.operator("paint.brush_select", text='Pinch/Magnify', icon='BRUSH_PINCH').sculpt_tool = 'PINCH'
+ # 9 - TOP - RIGHT
+ pie.operator("sculpt.polish", text='Polish', icon='BRUSH_FLATTEN')
+ # 1 - BOTTOM - LEFT
+ box = pie.split().column()
+ row = box.row(align=True)
+ box.operator("paint.brush_select", text='Twist', icon='BRUSH_ROTATE').sculpt_tool = 'ROTATE'
+ box.operator("paint.brush_select", text='Scrape/Peaks', icon='BRUSH_SCRAPE').sculpt_tool = 'SCRAPE'
+ box.operator("sculpt.sculptraw", text='SculptDraw', icon='BRUSH_SCULPT_DRAW')
+ box.operator("paint.brush_select", text='Mask', icon='BRUSH_MASK').sculpt_tool = 'MASK'
+ # 3 - BOTTOM - RIGHT
+ box = pie.split().column()
+ row = box.row(align=True)
+ box.operator("paint.brush_select", text='Layer', icon='BRUSH_LAYER').sculpt_tool = 'LAYER'
+ box.operator("paint.brush_select", text='Nudge', icon='BRUSH_NUDGE').sculpt_tool = 'NUDGE'
+ box.operator("paint.brush_select", text='Thumb', icon='BRUSH_THUMB').sculpt_tool = 'THUMB'
+ box.operator("paint.brush_select", text='Fill/Deepen', icon='BRUSH_FILL').sculpt_tool = 'FILL'
+
+classes = (
+ PieSculptPie,
+ PieSculpttwo,
+ SculptPolish,
+ SculptSculptDraw,
+ )
+
+addon_keymaps = []
+
+
+def register():
+ for cls in classes:
+ bpy.utils.register_class(cls)
+ wm = bpy.context.window_manager
+
+ if wm.keyconfigs.addon:
+ # Sculpt Pie Menu
+ km = wm.keyconfigs.addon.keymaps.new(name='Sculpt')
+ kmi = km.keymap_items.new('wm.call_menu_pie', 'W', 'PRESS')
+ kmi.properties.name = "pie.sculpt"
+# kmi.active = True
+ addon_keymaps.append((km, kmi))
+
+ # Sculpt Pie Menu 2
+ km = wm.keyconfigs.addon.keymaps.new(name='Sculpt')
+ kmi = km.keymap_items.new('wm.call_menu_pie', 'W', 'PRESS', alt=True)
+ kmi.properties.name = "pie.sculpttwo"
+# kmi.active = True
+ addon_keymaps.append((km, kmi))
+
+
+def unregister():
+ for cls in classes:
+ bpy.utils.unregister_class(cls)
+ wm = bpy.context.window_manager
+
+ kc = wm.keyconfigs.addon
+ if kc:
+ km = kc.keymaps['Sculpt']
+ for kmi in km.keymap_items:
+ if kmi.idname == 'wm.call_menu_pie':
+ if kmi.properties.name == "pie.sculpt":
+ km.keymap_items.remove(kmi)
+
+ kc = wm.keyconfigs.addon
+ if kc:
+ km = kc.keymaps['Sculpt']
+ for kmi in km.keymap_items:
+ if kmi.idname == 'wm.call_menu_pie':
+ if kmi.properties.name == "pie.sculpttwo":
+ km.keymap_items.remove(kmi)
+
+if __name__ == "__main__":
+ register()
diff --git a/space_view3d_pie_menus/pie_select_menu/__init__.py b/space_view3d_pie_menus/pie_select_menu/__init__.py
new file mode 100644
index 00000000..b837b2aa
--- /dev/null
+++ b/space_view3d_pie_menus/pie_select_menu/__init__.py
@@ -0,0 +1,198 @@
+# ##### 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": "Hotkey: 'A'",
+ "description": "Object/Edit mode Selection Menu",
+ # "author": "pitiwazou, meta-androcto",
+ # "version": (0, 1, 0),
+ "blender": (2, 77, 0),
+ "location": "3D View",
+ "warning": "",
+ "wiki_url": "",
+ "category": "Select Pie"
+ }
+
+import bpy
+from bpy.types import (
+ Menu,
+ Operator,
+ )
+
+# Pie Selection Object Mode - A
+
+
+class PieSelectionsMore(Menu):
+ bl_idname = "pie.selectionsmore"
+ bl_label = "Pie Selections Object Mode"
+
+ def draw(self, context):
+ layout = self.layout
+ pie = layout.menu_pie()
+ box = pie.split().column()
+ row = box.row(align=True)
+ box.operator("object.select_by_type", text="Select By Type", icon='SNAP_VOLUME')
+ box.operator("object.select_grouped", text="Select Grouped", icon='ROTATE')
+ box.operator("object.select_linked", text="Select Linked", icon='CONSTRAINT_BONE')
+ box.menu("VIEW3D_MT_select_object_more_less", text="More/Less")
+
+# Pie Selection Object Mode - A
+
+
+class PieSelectionsOM(Menu):
+ bl_idname = "pie.selectionsom"
+ bl_label = "Pie Selections Object Mode"
+
+ def draw(self, context):
+ layout = self.layout
+ pie = layout.menu_pie()
+ # 4 - LEFT
+ pie.operator("object.select_by_layer", text="Select By Layer", icon='GROUP_VERTEX')
+ # 6 - RIGHT
+ pie.operator("object.select_random", text="Select Random", icon='GROUP_VERTEX')
+ # 2 - BOTTOM
+ pie.operator("object.select_all", text="Invert Selection", icon='ZOOM_PREVIOUS').action = 'INVERT'
+ # 8 - TOP
+ pie.operator("object.select_all", text="Select All Toggle", icon='RENDER_REGION').action = 'TOGGLE'
+ # 7 - TOP - LEFT
+ pie.operator("view3d.select_circle", text="Circle Select", icon='BORDER_LASSO')
+ # 9 - TOP - RIGHT
+ pie.operator("view3d.select_border", text="Border Select", icon='BORDER_RECT')
+ # 1 - BOTTOM - LEFT
+ pie.operator("object.select_camera", text="Select Camera", icon='CAMERA_DATA')
+ # 3 - BOTTOM - RIGHT
+ pie.menu("pie.selectionsmore", text="Select More", icon='GROUP_VERTEX')
+
+# Pie Selection Edit Mode
+
+
+class PieSelectionsEM(Menu):
+ bl_idname = "pie.selectionsem"
+ bl_label = "Pie Selections Edit Mode"
+
+ def draw(self, context):
+ layout = self.layout
+ pie = layout.menu_pie()
+ # 4 - LEFT
+ pie.operator("mesh.loop_multi_select", text="Select Ring", icon='ZOOM_PREVIOUS').ring = True
+ # 6 - RIGHT
+ pie.operator("mesh.loop_multi_select", text="Select Loop", icon='ZOOM_PREVIOUS').ring = False
+ # 2 - BOTTOM
+ pie.operator("mesh.select_all", text="Invert Selection", icon='ZOOM_PREVIOUS').action = 'INVERT'
+ # 8 - TOP
+ pie.operator("mesh.select_all", text="Select All Toggle", icon='RENDER_REGION').action = 'TOGGLE'
+ # 7 - TOP - LEFT
+ pie.operator("view3d.select_circle", text="Circle Select", icon='BORDER_LASSO')
+ # 9 - TOP - RIGHT
+ pie.operator("view3d.select_border", text="Border Select", icon='BORDER_RECT')
+ # 1 - BOTTOM - LEFT
+ box = pie.split().column()
+ row = box.row(align=True)
+ box.operator("mesh.select_nth", text="Checker Select", icon='PARTICLE_POINT')
+ box.operator("mesh.loop_to_region", text="Select Loop Inner Region", icon='FACESEL')
+ box.operator("mesh.select_similar", text="Select Similar", icon='GHOST')
+ # 3 - BOTTOM - RIGHT
+ pie.menu("object.selectallbyselection", text="Multi Select", icon='RENDER_REGION')
+
+# Select All By Selection
+
+
+class SelectAllBySelection(Menu):
+ bl_idname = "object.selectallbyselection"
+ bl_label = "Verts Edges Faces"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
+
+ prop = layout.operator("wm.context_set_value", text="Vertex Select",
+ icon='VERTEXSEL')
+ prop.value = "(True, False, False)"
+ prop.data_path = "tool_settings.mesh_select_mode"
+
+ prop = layout.operator("wm.context_set_value", text="Edge Select",
+ icon='EDGESEL')
+ prop.value = "(False, True, False)"
+ prop.data_path = "tool_settings.mesh_select_mode"
+
+ prop = layout.operator("wm.context_set_value", text="Face Select",
+ icon='FACESEL')
+ prop.value = "(False, False, True)"
+ prop.data_path = "tool_settings.mesh_select_mode"
+
+ prop = layout.operator("wm.context_set_value",
+ text="Vertex & Edge & Face Select",
+ icon='SNAP_VOLUME')
+ prop.value = "(True, True, True)"
+ prop.data_path = "tool_settings.mesh_select_mode"
+
+classes = (
+ PieSelectionsOM,
+ PieSelectionsEM,
+ SelectAllBySelection,
+ PieSelectionsMore,
+ )
+
+addon_keymaps = []
+
+
+def register():
+ for cls in classes:
+ bpy.utils.register_class(cls)
+ wm = bpy.context.window_manager
+
+ if wm.keyconfigs.addon:
+ # Selection Object Mode
+ km = wm.keyconfigs.addon.keymaps.new(name='Object Mode')
+ kmi = km.keymap_items.new('wm.call_menu_pie', 'A', 'PRESS')
+ kmi.properties.name = "pie.selectionsom"
+ addon_keymaps.append((km, kmi))
+
+ # Selection Edit Mode
+ km = wm.keyconfigs.addon.keymaps.new(name='Mesh')
+ kmi = km.keymap_items.new('wm.call_menu_pie', 'A', 'PRESS')
+ kmi.properties.name = "pie.selectionsem"
+ addon_keymaps.append((km, kmi))
+
+
+def unregister():
+ for cls in classes:
+ bpy.utils.unregister_class(cls)
+ wm = bpy.context.window_manager
+
+ kc = wm.keyconfigs.addon
+ if kc:
+ km = kc.keymaps['Object Mode']
+ for kmi in km.keymap_items:
+ if kmi.idname == 'wm.call_menu_pie':
+ if kmi.properties.name == "pie.selectionsom":
+ km.keymap_items.remove(kmi)
+
+ kc = wm.keyconfigs.addon
+ if kc:
+ km = kc.keymaps['Mesh']
+ for kmi in km.keymap_items:
+ if kmi.idname == 'wm.call_menu_pie':
+ if kmi.properties.name == "pie.selectionsem":
+ km.keymap_items.remove(kmi)
+
+if __name__ == "__main__":
+ register()
diff --git a/space_view3d_pie_menus/pie_shading_menu/__init__.py b/space_view3d_pie_menus/pie_shading_menu/__init__.py
new file mode 100644
index 00000000..8c9f1f50
--- /dev/null
+++ b/space_view3d_pie_menus/pie_shading_menu/__init__.py
@@ -0,0 +1,94 @@
+# ##### 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": "Hotkey: 'Z'",
+ "description": "Viewport Shading Menus",
+ # "author": "pitiwazou, meta-androcto",
+ # "version": (0, 1, 0),
+ "blender": (2, 77, 0),
+ "location": "3D View",
+ "warning": "",
+ "wiki_url": "",
+ "category": "Shading Pie"
+ }
+
+import bpy
+from bpy.types import Menu
+
+# Pie Shading - Z
+
+
+class PieShadingView(Menu):
+ bl_idname = "pie.shadingview"
+ bl_label = "Pie Shading"
+
+ 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")
+
+
+classes = (
+ PieShadingView,
+ )
+
+addon_keymaps = []
+
+
+def register():
+ for cls in classes:
+ bpy.utils.register_class(cls)
+ wm = bpy.context.window_manager
+
+ if wm.keyconfigs.addon:
+ # Shading
+ km = wm.keyconfigs.addon.keymaps.new(name='3D View Generic', space_type='VIEW_3D')
+ kmi = km.keymap_items.new('wm.call_menu_pie', 'Z', 'PRESS')
+ kmi.properties.name = "pie.shadingview"
+# kmi.active = True
+ addon_keymaps.append((km, kmi))
+
+
+def unregister():
+ for cls in classes:
+ bpy.utils.unregister_class(cls)
+ wm = bpy.context.window_manager
+
+ kc = wm.keyconfigs.addon
+ if kc:
+ km = kc.keymaps['3D View Generic']
+ for kmi in km.keymap_items:
+ if kmi.idname == 'wm.call_menu_pie':
+ if kmi.properties.name == "pie.shadingview":
+ km.keymap_items.remove(kmi)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/space_view3d_pie_menus/pie_snap_menu/__init__.py b/space_view3d_pie_menus/pie_snap_menu/__init__.py
new file mode 100644
index 00000000..9e58e608
--- /dev/null
+++ b/space_view3d_pie_menus/pie_snap_menu/__init__.py
@@ -0,0 +1,269 @@
+# ##### 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": "Hotkey: 'Ctrl Shift Tab'",
+ "description": "Snap Element Menu",
+ # "author": "pitiwazou, meta-androcto",
+ # "version": (0, 1, 0),
+ "blender": (2, 77, 0),
+ "location": "3d View",
+ "warning": "",
+ "wiki_url": "",
+ "category": "Snap Element Pie"
+ }
+
+import bpy
+from bpy.types import (
+ Menu,
+ Operator,
+ )
+
+# Pie Snap - Shift + Tab
+
+
+class PieSnaping(Menu):
+ bl_idname = "pie.snapping"
+ bl_label = "Pie Snapping"
+
+ def draw(self, context):
+ layout = self.layout
+ pie = layout.menu_pie()
+ # 4 - LEFT
+ pie.operator("snap.vertex", text="Vertex", icon='SNAP_VERTEX')
+ # 6 - RIGHT
+ pie.operator("snap.face", text="Face", icon='SNAP_FACE')
+ # 2 - BOTTOM
+ pie.operator("snap.edge", text="Edge", icon='SNAP_EDGE')
+ # 8 - TOP
+ pie.prop(context.tool_settings, "use_snap", text="Snap On/Off")
+ # 7 - TOP - LEFT
+ pie.operator("snap.volume", text="Volume", icon='SNAP_VOLUME')
+ # 9 - TOP - RIGHT
+ pie.operator("snap.increment", text="Increment", icon='SNAP_INCREMENT')
+ # 1 - BOTTOM - LEFT
+ pie.operator("snap.alignrotation", text="Align rotation", icon='SNAP_NORMAL')
+ # 3 - BOTTOM - RIGHT
+ pie.operator("wm.call_menu_pie", text="Snap Target", icon='SNAP_SURFACE').name = "snap.targetmenu"
+
+
+class SnapActive(Operator):
+ bl_idname = "snap.active"
+ bl_label = "Snap Active"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+
+ if ts.use_snap == True:
+ ts.use_snap = False
+
+ elif ts.use_snap == False:
+ ts.use_snap = True
+
+ return {'FINISHED'}
+
+
+class SnapVolume(Operator):
+ bl_idname = "snap.volume"
+ bl_label = "Snap Volume"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+ if ts.use_snap == False:
+ ts.use_snap = True
+ ts.snap_element = 'VOLUME'
+
+ if ts.snap_element != 'VOLUME':
+ ts.snap_element = 'VOLUME'
+ return {'FINISHED'}
+
+
+class SnapFace(Operator):
+ bl_idname = "snap.face"
+ bl_label = "Snap Face"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+
+ if ts.use_snap == False:
+ ts.use_snap = True
+ ts.snap_element = 'FACE'
+
+ if ts.snap_element != 'FACE':
+ ts.snap_element = 'FACE'
+ return {'FINISHED'}
+
+
+class SnapEdge(Operator):
+ bl_idname = "snap.edge"
+ bl_label = "Snap Edge"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+
+ if ts.use_snap == False:
+ ts.use_snap = True
+ ts.snap_element = 'EDGE'
+
+ if ts.snap_element != 'EDGE':
+ ts.snap_element = 'EDGE'
+ return {'FINISHED'}
+
+
+class SnapVertex(Operator):
+ bl_idname = "snap.vertex"
+ bl_label = "Snap Vertex"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+
+ if ts.use_snap == False:
+ ts.use_snap = True
+ ts.snap_element = 'VERTEX'
+
+ if ts.snap_element != 'VERTEX':
+ ts.snap_element = 'VERTEX'
+ return {'FINISHED'}
+
+
+class SnapIncrement(Operator):
+ bl_idname = "snap.increment"
+ bl_label = "Snap Increment"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+
+ if ts.use_snap == False:
+ ts.use_snap = True
+ ts.snap_element = 'INCREMENT'
+
+ if ts.snap_element != 'INCREMENT':
+ ts.snap_element = 'INCREMENT'
+ return {'FINISHED'}
+
+
+class SnapAlignRotation(Operator):
+ bl_idname = "snap.alignrotation"
+ bl_label = "Snap Align rotation"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ ts = context.tool_settings
+
+ if ts.use_snap_align_rotation == True:
+ ts.use_snap_align_rotation = False
+
+ elif ts.use_snap_align_rotation == False:
+ ts.use_snap_align_rotation = True
+
+ return {'FINISHED'}
+
+
+class SnapTargetVariable(Operator):
+ bl_idname = "object.snaptargetvariable"
+ bl_label = "Snap Target Variable"
+ bl_options = {'REGISTER', 'UNDO'}
+ variable = bpy.props.StringProperty()
+
+ @classmethod
+ def poll(cls, context):
+ return True
+
+ def execute(self, context):
+ ts = context.tool_settings
+
+ ts.snap_target = self.variable
+ return {'FINISHED'}
+
+# Menu Snap Target - Shift + Tab
+
+
+class SnapTargetMenu(Menu):
+ bl_idname = "snap.targetmenu"
+ bl_label = "Snap Target Menu"
+
+ def draw(self, context):
+ layout = self.layout
+ pie = layout.menu_pie()
+ # 4 - LEFT
+ pie.operator("object.snaptargetvariable", text="Active").variable = 'ACTIVE'
+ # 6 - RIGHT
+ pie.operator("object.snaptargetvariable", text="Median").variable = 'MEDIAN'
+ # 2 - BOTTOM
+ pie.operator("object.snaptargetvariable", text="Center").variable = 'CENTER'
+ # 8 - TOP
+ pie.operator("object.snaptargetvariable", text="Closest").variable = 'CLOSEST'
+ # 7 - TOP - LEFT
+ # 9 - TOP - RIGHT
+ # 1 - BOTTOM - LEFT
+ # 3 - BOTTOM - RIGHT
+# Pie Snapping - Shift + Tab
+
+classes = (
+ PieSnaping,
+ SnapTargetMenu,
+ SnapActive,
+ SnapVolume,
+ SnapFace,
+ SnapEdge,
+ SnapVertex,
+ SnapIncrement,
+ SnapAlignRotation,
+ SnapTargetVariable
+ )
+
+addon_keymaps = []
+
+
+def register():
+ for cls in classes:
+ bpy.utils.register_class(cls)
+ wm = bpy.context.window_manager
+
+ if wm.keyconfigs.addon:
+ # Snapping
+ km = wm.keyconfigs.addon.keymaps.new(name='3D View Generic', space_type='VIEW_3D')
+ kmi = km.keymap_items.new('wm.call_menu_pie', 'TAB', 'PRESS', ctrl=True, shift=True)
+ kmi.properties.name = "pie.snapping"
+# kmi.active = True
+ addon_keymaps.append((km, kmi))
+
+
+def unregister():
+ for cls in classes:
+ bpy.utils.unregister_class(cls)
+ wm = bpy.context.window_manager
+
+ kc = wm.keyconfigs.addon
+ if kc:
+ km = kc.keymaps['3D View Generic']
+ for kmi in km.keymap_items:
+ if kmi.idname == 'wm.call_menu_pie':
+ if kmi.properties.name == "pie.snapping":
+ km.keymap_items.remove(kmi)
+
+if __name__ == "__main__":
+ register()
diff --git a/space_view3d_pie_menus/pie_views_numpad_menu/__init__.py b/space_view3d_pie_menus/pie_views_numpad_menu/__init__.py
new file mode 100644
index 00000000..fe2b8258
--- /dev/null
+++ b/space_view3d_pie_menus/pie_views_numpad_menu/__init__.py
@@ -0,0 +1,197 @@
+# ##### 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": "Hotkey: 'Q'",
+ "description": "Viewport Numpad Menus",
+ # "author": "pitiwazou, meta-androcto",
+ # "version": (0, 1, 0),
+ "blender": (2, 77, 0),
+ "location": "Q key",
+ "warning": "",
+ "wiki_url": "",
+ "category": "View Numpad Pie"
+ }
+
+import bpy
+from bpy.types import (
+ Menu,
+ Operator,
+ )
+from bpy.props import (
+ StringProperty,
+ )
+
+# Lock Camera Transforms
+
+
+class LockTransforms(Operator):
+ bl_idname = "object.locktransforms"
+ bl_label = "Lock Object Transforms"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ obj = context.object
+ if obj.lock_rotation[0] == False:
+ obj.lock_rotation[0] = True
+ obj.lock_rotation[1] = True
+ obj.lock_rotation[2] = True
+ obj.lock_location[0] = True
+ obj.lock_location[1] = True
+ obj.lock_location[2] = True
+ obj.lock_scale[0] = True
+ obj.lock_scale[1] = True
+ obj.lock_scale[2] = True
+
+ elif context.object.lock_rotation[0] == True:
+ obj.lock_rotation[0] = False
+ obj.lock_rotation[1] = False
+ obj.lock_rotation[2] = False
+ obj.lock_location[0] = False
+ obj.lock_location[1] = False
+ obj.lock_location[2] = False
+ obj.lock_scale[0] = False
+ obj.lock_scale[1] = False
+ obj.lock_scale[2] = False
+ return {'FINISHED'}
+
+
+# Pie View All Sel Glob Etc - Q
+
+
+class PieViewallSelGlobEtc(Menu):
+ bl_idname = "pie.vieallselglobetc"
+ bl_label = "Pie View All Sel Glob..."
+
+ def draw(self, context):
+ layout = self.layout
+ pie = layout.menu_pie()
+ # 4 - LEFT
+ pie.operator("view3d.view_all", text="View All").center = True
+ # 6 - RIGHT
+ pie.operator("view3d.view_selected", text="View Selected")
+ # 2 - BOTTOM
+ pie.operator("view3d.view_persportho", text="Persp/Ortho", icon='RESTRICT_VIEW_OFF')
+ # 8 - TOP
+ pie.operator("view3d.localview", text="Local/Global")
+ # 7 - TOP - LEFT
+ pie.operator("screen.region_quadview", text="Toggle Quad View", icon='SPLITSCREEN')
+ # 1 - BOTTOM - LEFT
+ pie.operator("wm.call_menu_pie", text="Previous Menu", icon='BACK').name = "pie.viewnumpad"
+ # 9 - TOP - RIGHT
+ pie.operator("screen.screen_full_area", text="Full Screen", icon='FULLSCREEN_ENTER')
+ # 3 - BOTTOM - RIGHT
+
+# Pie views numpad - Q
+
+
+class PieViewNumpad(Menu):
+ bl_idname = "pie.viewnumpad"
+ bl_label = "Pie Views Ortho"
+
+ def draw(self, context):
+ layout = self.layout
+ ob = context.object
+ pie = layout.menu_pie()
+ scene = context.scene
+ rd = scene.render
+
+ # 4 - LEFT
+ pie.operator("view3d.viewnumpad", text="Left", icon='TRIA_LEFT').type = 'LEFT'
+ # 6 - RIGHT
+ pie.operator("view3d.viewnumpad", text="Right", icon='TRIA_RIGHT').type = 'RIGHT'
+ # 2 - BOTTOM
+ pie.operator("view3d.viewnumpad", text="Bottom", icon='TRIA_DOWN').type = 'BOTTOM'
+ # 8 - TOP
+ pie.operator("view3d.viewnumpad", text="Top", icon='TRIA_UP').type = 'TOP'
+ # 7 - TOP - LEFT
+ pie.operator("view3d.viewnumpad", text="Front").type = 'FRONT'
+ # 9 - TOP - RIGHT
+ pie.operator("view3d.viewnumpad", text="Back").type = 'BACK'
+ # 1 - BOTTOM - LEFT
+ box = pie.split().column()
+ row = box.row(align=True)
+ if context.space_data.lock_camera == False:
+ row.operator("wm.context_toggle", text="Lock Cam to View",
+ icon='UNLOCKED').data_path = "space_data.lock_camera"
+ elif context.space_data.lock_camera == True:
+ row.operator("wm.context_toggle", text="Lock Cam to View",
+ icon='LOCKED').data_path = "space_data.lock_camera"
+
+ row = box.row(align=True)
+ row.operator("view3d.viewnumpad", text="View Cam", icon='VISIBLE_IPO_ON').type = 'CAMERA'
+ row.operator("view3d.camera_to_view", text="Cam to view", icon='MAN_TRANS')
+
+ if ob.lock_rotation[0] == False:
+ row = box.row(align=True)
+ row.operator("object.locktransforms", text="Lock Transforms", icon='LOCKED')
+
+ elif ob.lock_rotation[0] == True:
+ row = box.row(align=True)
+ row.operator("object.locktransforms", text="UnLock Transforms", icon='UNLOCKED')
+ row = box.row(align=True)
+ row.prop(rd, "use_border", text="Border")
+ # 3 - BOTTOM - RIGHT
+ pie.operator("wm.call_menu_pie", text="View All Pie", icon='BBOX').name = "pie.vieallselglobetc"
+
+classes = (
+ PieViewNumpad,
+ LockTransforms,
+ PieViewallSelGlobEtc,
+ )
+
+addon_keymaps = []
+
+
+def register():
+ for cls in classes:
+ bpy.utils.register_class(cls)
+
+# Active Camera
+ bpy.types.Scene.cameratoto = bpy.props.StringProperty(default="")
+
+ wm = bpy.context.window_manager
+
+ if wm.keyconfigs.addon:
+ # Views numpad
+ km = wm.keyconfigs.addon.keymaps.new(name='3D View Generic', space_type='VIEW_3D')
+ kmi = km.keymap_items.new('wm.call_menu_pie', 'Q', 'PRESS')
+ kmi.properties.name = "pie.viewnumpad"
+# kmi.active = True
+ addon_keymaps.append((km, kmi))
+
+
+def unregister():
+ for cls in classes:
+ bpy.utils.unregister_class(cls)
+ wm = bpy.context.window_manager
+
+ kc = wm.keyconfigs.addon
+ if kc:
+ km = kc.keymaps['3D View Generic']
+ for kmi in km.keymap_items:
+ if kmi.idname == 'wm.call_menu_pie':
+ if kmi.properties.name == "pie.viewnumpad":
+ km.keymap_items.remove(kmi)
+
+ del bpy.types.Scene.cameratoto
+
+if __name__ == "__main__":
+ register()
diff --git a/space_view3d_pie_menus/utils.py b/space_view3d_pie_menus/utils.py
new file mode 100644
index 00000000..045a158a
--- /dev/null
+++ b/space_view3d_pie_menus/utils.py
@@ -0,0 +1,327 @@
+# ##### 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>
+
+import bpy
+
+
+class AddonPreferences:
+ _module = {}
+
+ @classmethod
+ def get_prefs(cls, package=''):
+ if not package:
+ package = __package__
+ if '.' in package:
+ pkg, name = package.split('.')
+ # key = cls.__qualname__
+ if package in cls._module:
+ mod = cls._module[package]
+ else:
+ import importlib
+ mod = cls._module[package] = importlib.import_module(pkg)
+ return mod.get_addon_preferences(name)
+ else:
+ context = bpy.context
+ return context.user_preferences.addons[package].preferences
+
+ @classmethod
+ def register(cls):
+ if '.' in __package__:
+ cls.get_prefs()
+
+ @classmethod
+ def unregister(cls):
+ cls._module.clear()
+
+
+class SpaceProperty:
+ """
+ bpy.types.Space #Add the virtual property in
+
+ # Instantiation
+ space_prop = SpaceProperty(
+ [[bpy.types.SpaceView3D, 'lock_cursor_location',
+ bpy.props.BoolProperty()]])
+
+ # When drawing
+ def draw(self, context):
+ layout = self.layout
+ view = context.space_data
+ prop = space_prop.get_prop(view, 'lock_cursor_location')
+ layout.prop(prop, 'lock_cursor_location')
+
+ # register / unregister
+ def register():
+ space_prop.register()
+
+ def unregister():
+ space_prop.unregister()
+ """
+
+ space_types = {
+ 'EMPTY': bpy.types.Space,
+ 'NONE': bpy.types.Space,
+ 'CLIP_EDITOR': bpy.types.SpaceClipEditor,
+ 'CONSOLE': bpy.types.SpaceConsole,
+ 'DOPESHEET_EDITOR': bpy.types.SpaceDopeSheetEditor,
+ 'FILE_BROWSER': bpy.types.SpaceFileBrowser,
+ 'GRAPH_EDITOR': bpy.types.SpaceGraphEditor,
+ 'IMAGE_EDITOR': bpy.types.SpaceImageEditor,
+ 'INFO': bpy.types.SpaceInfo,
+ 'LOGIC_EDITOR': bpy.types.SpaceLogicEditor,
+ 'NLA_EDITOR': bpy.types.SpaceNLA,
+ 'NODE_EDITOR': bpy.types.SpaceNodeEditor,
+ 'OUTLINER': bpy.types.SpaceOutliner,
+ 'PROPERTIES': bpy.types.SpaceProperties,
+ 'SEQUENCE_EDITOR': bpy.types.SpaceSequenceEditor,
+ 'TEXT_EDITOR': bpy.types.SpaceTextEditor,
+ 'TIMELINE': bpy.types.SpaceTimeline,
+ 'USER_PREFERENCES': bpy.types.SpaceUserPreferences,
+ 'VIEW_3D': bpy.types.SpaceView3D,
+ }
+ # space_types_r = {v: k for k, v in space_types.items()}
+
+ def __init__(self, *props):
+ """
+ :param props: [[space_type, attr, prop], ...]
+ [[Or string bpy.types.Space, String,
+ bpy.props.***()恋PropertyGroup], ...]
+ bpy.types.PropertyGroup In advance if you use register_class()so
+ It is registered
+ :type props: list[list]
+ """
+ self.props = [list(elem) for elem in props]
+ for elem in self.props:
+ space_type = elem[0]
+ if isinstance(space_type, str):
+ elem[0] = self.space_types[space_type]
+ self.registered = []
+ self.save_pre = self.save_post = self.load_post = None
+
+ def gen_save_pre(self):
+ @bpy.app.handlers.persistent
+ def save_pre(dummy):
+ wm = bpy.context.window_manager
+ for (space_type, attr, prop), (cls, wm_prop_name) in zip(
+ self.props, self.registered):
+ if wm_prop_name not in wm:
+ continue
+ d = {p['name']: p for p in wm[wm_prop_name]} # not p.name
+ for screen in bpy.data.screens:
+ ls = []
+ for area in screen.areas:
+ for space in area.spaces:
+ if isinstance(space, space_type):
+ key = str(space.as_pointer())
+ if key in d:
+ ls.append(d[key])
+ else:
+ ls.append({})
+ screen[wm_prop_name] = ls
+ self.save_pre = save_pre
+ return save_pre
+
+ def gen_save_post(self):
+ @bpy.app.handlers.persistent
+ def save_post(dummy):
+ # clean up
+ for cls, wm_prop_name in self.registered:
+ for screen in bpy.data.screens:
+ if wm_prop_name in screen:
+ del screen[wm_prop_name]
+ self.save_post = save_post
+ return save_post
+
+ def gen_load_post(self):
+ @bpy.app.handlers.persistent
+ def load_post(dummy):
+ from collections import OrderedDict
+ for (space_type, attr, prop), (cls, wm_prop_name) in zip(
+ self.props, self.registered):
+ d = OrderedDict()
+ for screen in bpy.data.screens:
+ if wm_prop_name not in screen:
+ continue
+
+ spaces = []
+ for area in screen.areas:
+ for space in area.spaces:
+ if isinstance(space, space_type):
+ spaces.append(space)
+
+ for space, p in zip(spaces, screen[wm_prop_name]):
+ key = p['name'] = str(space.as_pointer())
+ d[key] = p
+ if d:
+ bpy.context.window_manager[wm_prop_name] = list(d.values())
+
+ # clean up
+ for cls, wm_prop_name in self.registered:
+ for screen in bpy.data.screens:
+ if wm_prop_name in screen:
+ del screen[wm_prop_name]
+
+ self.load_post = load_post
+ return load_post
+
+ def get_all(self, space_type=None, attr=''):
+ """
+ :param space_type: If the property is only only one optional
+ :type space_type: bpy.types.Space
+ :param attr: If the property is only only one optional
+ :type attr: str
+ :return:
+ :rtype:
+ """
+ if space_type and isinstance(space_type, str):
+ space_type = self.space_types.get(space_type)
+ context = bpy.context
+ for (st, attri, prop), (cls, wm_prop_name) in zip(
+ self.props, self.registered):
+ if (st == space_type or issubclass(space_type, st) or
+ not space_type and len(self.props) == 1):
+ if attri == attr or not attr and len(self.props) == 1:
+ seq = getattr(context.window_manager, wm_prop_name)
+ return seq
+
+ def get(self, space, attr=''):
+ """
+ :type space: bpy.types.Space
+ :param attr: If the property is only only one optional
+ :type attr: str
+ :return:
+ :rtype:
+ """
+ seq = self.get_all(type(space), attr)
+ if seq is not None:
+ key = str(space.as_pointer())
+ if key not in seq:
+ item = seq.add()
+ item.name = key
+ return seq[key]
+
+ def _property_name(self, space_type, attr):
+ return space_type.__name__.lower() + '_' + attr
+
+ def register(self):
+ import inspect
+ from bpy.types import WindowManager
+ wm = bpy.context.window_manager
+
+ for space_type, attr, prop in self.props:
+ if inspect.isclass(prop) and \
+ issubclass(prop, bpy.types.PropertyGroup):
+ cls = prop
+ else:
+ name = 'WM_PG_' + space_type.__name__ + '_' + attr
+ cls = type(name, (bpy.types.PropertyGroup,), {attr: prop})
+ bpy.utils.register_class(cls)
+
+ collection_prop = bpy.props.CollectionProperty(type=cls)
+ wm_prop_name = self._property_name(space_type, attr)
+ setattr(WindowManager, wm_prop_name, collection_prop)
+
+ self.registered.append((cls, wm_prop_name))
+
+ def gen():
+ def get(self):
+ seq = getattr(wm, wm_prop_name)
+ key = str(self.as_pointer())
+ if key not in seq:
+ item = seq.add()
+ item.name = key
+ if prop == cls:
+ return seq[key]
+ else:
+ return getattr(seq[key], attr)
+
+ def set(self, value):
+ seq = getattr(wm, wm_prop_name)
+ key = str(self.as_pointer())
+ if key not in seq:
+ item = seq.add()
+ item.name = key
+ if prop != cls: # PropertyGroup It is not writable
+ return setattr(seq[key], attr, value)
+
+ return property(get, set)
+
+ setattr(space_type, attr, gen())
+
+ bpy.app.handlers.save_pre.append(self.gen_save_pre())
+ bpy.app.handlers.save_post.append(self.gen_save_post())
+ bpy.app.handlers.load_post.append(self.gen_load_post())
+
+ def unregister(self):
+ from bpy.types import WindowManager
+ wm = bpy.context.window_manager
+
+ bpy.app.handlers.save_pre.remove(self.save_pre)
+ bpy.app.handlers.save_post.remove(self.save_post)
+ bpy.app.handlers.load_post.remove(self.load_post)
+
+ for (space_type, attr, prop), (cls, wm_prop_name) in zip(
+ self.props, self.registered):
+ delattr(WindowManager, wm_prop_name)
+ if wm_prop_name in wm:
+ del wm[wm_prop_name]
+ delattr(space_type, attr)
+
+ if prop != cls:
+ # originally bpy.types.PropertyGroup Skip Nara
+ bpy.utils.unregister_class(cls)
+
+ for screen in bpy.data.screens:
+ if wm_prop_name in screen:
+ del screen[wm_prop_name]
+
+ self.registered.clear()
+
+
+def operator_call(op, *args, _scene_update=True, **kw):
+ """vawm Than
+ operator_call(bpy.ops.view3d.draw_nearest_element,
+ 'INVOKE_DEFAULT', type='ENABLE', _scene_update=False)
+ """
+ import bpy
+ from _bpy import ops as ops_module
+
+ BPyOpsSubModOp = op.__class__
+ op_call = ops_module.call
+ context = bpy.context
+
+ # Get the operator from blender
+ wm = context.window_manager
+
+ # run to account for any rna values the user changes.
+ if _scene_update:
+ BPyOpsSubModOp._scene_update(context)
+
+ if args:
+ C_dict, C_exec, C_undo = BPyOpsSubModOp._parse_args(args)
+ ret = op_call(op.idname_py(), C_dict, kw, C_exec, C_undo)
+ else:
+ ret = op_call(op.idname_py(), None, kw)
+
+ if 'FINISHED' in ret and context.window_manager == wm:
+ if _scene_update:
+ BPyOpsSubModOp._scene_update(context)
+
+ return ret