diff options
author | meta-androcto <meta.androcto1@gmail.com> | 2016-08-03 16:40:56 +0300 |
---|---|---|
committer | meta-androcto <meta.androcto1@gmail.com> | 2016-08-03 16:40:56 +0300 |
commit | 6ee6d9e44aefc6eb1e7cdbf3e8b1e62392f2df6a (patch) | |
tree | e68d2c86c2f0ae08e3e54147f38714d11f6578e7 /space_view3d_pie_menus | |
parent | 606fbde1c3968d2db1b7beb954a778a4997905c9 (diff) |
move 3d view pie menus to release re: T48709
Diffstat (limited to 'space_view3d_pie_menus')
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 |