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

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'bone_selection_groups.py')
-rw-r--r--bone_selection_groups.py244
1 files changed, 244 insertions, 0 deletions
diff --git a/bone_selection_groups.py b/bone_selection_groups.py
new file mode 100644
index 00000000..1c00bb13
--- /dev/null
+++ b/bone_selection_groups.py
@@ -0,0 +1,244 @@
+# ***** 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 LICENCE BLOCK *****
+
+bl_info = {
+ "name": "Bone Selection Groups",
+ "author": "Antony Riakiotakis",
+ "version": (1, 0, 2),
+ "blender": (2, 75, 0),
+ "location": "Properties > Object Buttons",
+ "description": "Operator and storage for restoration of bone selection state.",
+ "category": "Animation",
+}
+
+import bpy
+from bpy.types import (
+ Operator,
+ Panel,
+ UIList,
+)
+
+from bpy.props import (
+ StringProperty,
+ BoolProperty,
+ IntProperty,
+ FloatProperty,
+ EnumProperty,
+ CollectionProperty,
+ BoolVectorProperty,
+ FloatVectorProperty,
+)
+
+
+class POSE_PT_selection_sets(Panel):
+ bl_label = "Selection Sets"
+ bl_space_type = 'PROPERTIES'
+ bl_region_type = 'WINDOW'
+ bl_context = "data"
+
+ @classmethod
+ def poll(cls, context):
+ return context.object.type == 'ARMATURE'
+
+ def draw(self, context):
+ layout = self.layout
+
+ armature = context.object
+
+ # Rig type list
+ row = layout.row()
+ row.template_list(
+ "POSE_UL_selection_set", "",
+ armature, "selection_sets",
+ armature, "active_selection_set")
+
+ col = row.column()
+ colsub = col.column(align=True)
+ colsub.operator("pose.selection_set_add", icon='ZOOMIN', text="")
+ colsub.operator("pose.selection_set_remove", icon='ZOOMOUT', text="")
+
+ layout.operator("pose.selection_set_toggle")
+
+
+class POSE_UL_selection_set(UIList):
+ def draw_item(self, context, layout, data, set, icon, active_data, active_propname, index):
+ layout.prop(set, "name", text="", emboss=False)
+
+
+class SelectionEntry(bpy.types.PropertyGroup):
+ name = StringProperty(name="Bone Name")
+
+
+class SelectionSet(bpy.types.PropertyGroup):
+ name = StringProperty(name="Set Name")
+ bone_ids = CollectionProperty(type=SelectionEntry)
+
+
+class PluginOperator(Operator):
+ @classmethod
+ def poll(self, context):
+ return (context.object and
+ context.object.type == 'ARMATURE' and
+ context.mode == 'POSE')
+
+
+class POSE_OT_selection_set_add(PluginOperator):
+ bl_idname = "pose.selection_set_add"
+ bl_label = "Add Selection Set"
+ bl_options = {'UNDO', 'REGISTER'}
+
+ def execute(self, context):
+ keep = False
+ armature = context.object
+ pose = armature.pose
+
+ selection_set = armature.selection_sets.add()
+ selection_set.name = "SelectionSet.%d" % len(armature.selection_sets)
+ armature.active_selection_set = len(armature.selection_sets) - 1
+ for bone in pose.bones:
+ if (bone.bone.select):
+ bone_id = selection_set.bone_ids.add()
+ bone_id.name = bone.name
+ keep = True
+
+ if (not keep):
+ armature.selection_sets.remove(armature.active_selection_set)
+ numsets = len(armature.selection_sets)
+ if (armature.active_selection_set > (numsets - 1) and numsets > 0):
+ armature.active_selection_set = len(armature.selection_sets) - 1
+ return {'CANCELLED'}
+
+ return {'FINISHED'}
+
+
+class POSE_OT_selection_set_remove(PluginOperator):
+ bl_idname = "pose.selection_set_remove"
+ bl_label = "Delete Selection Set"
+ bl_options = {'UNDO', 'REGISTER'}
+
+ def execute(self, context):
+ armature = context.object
+
+ armature.selection_sets.remove(armature.active_selection_set)
+ numsets = len(armature.selection_sets)
+ if (armature.active_selection_set > (numsets - 1) and numsets > 0):
+ armature.active_selection_set = len(armature.selection_sets) - 1
+ return {'FINISHED'}
+
+
+class POSE_OT_selection_set_toggle(PluginOperator):
+ bl_idname = "pose.selection_set_toggle"
+ bl_label = "Toggle Selection Set"
+ bl_options = {'UNDO', 'REGISTER'}
+
+ def execute(self, context):
+ armature = context.object
+ pose = armature.pose
+
+ selection_set = armature.selection_sets[armature.active_selection_set]
+ for bone in pose.bones:
+ bone.bone.select = False
+
+ for bone in selection_set.bone_ids:
+ pose.bones[bone.name].bone.select = True
+
+ return {'FINISHED'}
+
+
+class MotionPathsCopyStartFrame(Operator):
+ bl_idname = "anim.motionpaths_copy_scene_startframe"
+ bl_label = "Copy Scene Start Frame"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ armature_paths = BoolProperty()
+
+ @classmethod
+ def poll(cls, context):
+ return (context.object)
+
+ def execute(self, context):
+ avs = None
+ motionpath = None
+ ob = context.object
+ scene = context.scene
+
+ if (self.armature_paths):
+ avs = ob.pose.animation_visualization
+ else:
+ avs = ob.animation_visualization
+
+ preview = scene.use_preview_range
+
+ if (avs):
+ motionpath = avs.motion_path
+
+ if (motionpath):
+ if (preview):
+ motionpath.frame_start = scene.frame_preview_start
+ motionpath.frame_end = scene.frame_preview_end
+ else:
+ motionpath.frame_start = scene.frame_start
+ motionpath.frame_end = scene.frame_end
+ else:
+ return {'CANCELLED'}
+
+ return {'FINISHED'}
+
+
+classes = (
+ POSE_PT_selection_sets,
+ POSE_UL_selection_set,
+ SelectionEntry,
+ SelectionSet,
+ POSE_OT_selection_set_add,
+ POSE_OT_selection_set_remove,
+ POSE_OT_selection_set_toggle,
+ MotionPathsCopyStartFrame
+)
+
+
+def copy_frames_armature(self, context):
+ layout = self.layout
+ layout.operator("anim.motionpaths_copy_scene_startframe").armature_paths = True
+
+
+def copy_frames_object(self, context):
+ layout = self.layout
+ layout.operator("anim.motionpaths_copy_scene_startframe").armature_paths = False
+
+
+def register():
+ for cls in classes:
+ bpy.utils.register_class(cls)
+
+ bpy.types.Object.selection_sets = CollectionProperty(type=SelectionSet)
+ bpy.types.Object.active_selection_set = IntProperty()
+ bpy.types.DATA_PT_motion_paths.append(copy_frames_armature)
+ bpy.types.OBJECT_PT_motion_paths.append(copy_frames_object)
+
+
+def unregister():
+ for cls in classes:
+ bpy.utils.unregister_class(cls)
+
+ del bpy.types.Object.selection_sets
+ del bpy.types.Object.active_selection_set
+
+
+if __name__ == "__main__":
+ register()