move 3d view pie menus to release re: T48709

This commit is contained in:
Brendon Murphy 2016-08-03 23:40:56 +10:00
parent 606fbde1c3
commit 6ee6d9e44a
19 changed files with 4319 additions and 0 deletions

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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