Cleanup: quiet strict name warnings for addons a..h.
[blender-addons.git] / rigify / ui.py
blob458dceed350ecd72ec4bc21ccd1471d39e415ecd
1 #====================== BEGIN GPL LICENSE BLOCK ======================
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 #======================= END GPL LICENSE BLOCK ========================
19 # <pep8 compliant>
21 import bpy
22 from bpy.props import StringProperty
23 from mathutils import Color
25 from .utils import get_rig_type, MetarigError
26 from .utils import write_metarig, write_widget
27 from .utils import unique_name
28 from .utils import upgradeMetarigTypes, outdated_types
29 from .utils import get_keyed_frames, bones_in_frame
30 from .utils import overwrite_prop_animation
31 from .rigs.utils import get_limb_generated_names
32 from . import rig_lists
33 from . import generate
34 from . import rot_mode
37 class DATA_PT_rigify_buttons(bpy.types.Panel):
38 bl_label = "Rigify Buttons"
39 bl_space_type = 'PROPERTIES'
40 bl_region_type = 'WINDOW'
41 bl_context = "data"
43 @classmethod
44 def poll(cls, context):
45 return context.object.type == 'ARMATURE' and context.active_object.data.get("rig_id") is None
47 def draw(self, context):
48 C = context
49 layout = self.layout
50 obj = context.object
51 id_store = C.window_manager
53 if obj.mode in {'POSE', 'OBJECT'}:
55 WARNING = "Warning: Some features may change after generation"
56 show_warning = False
57 show_update_metarig = False
58 show_not_updatable = False
60 check_props = ['IK_follow', 'root/parent', 'FK_limb_follow', 'IK_Stretch']
62 for obj in bpy.data.objects:
63 if type(obj.data) != bpy.types.Armature:
64 continue
65 for bone in obj.pose.bones:
66 if bone.bone.layers[30] and (list(set(bone.keys()) & set(check_props))):
67 show_warning = True
68 break
69 for b in obj.pose.bones:
70 if b.rigify_type in outdated_types.keys():
71 if outdated_types[b.rigify_type]:
72 show_update_metarig = True
73 else:
74 show_update_metarig = False
75 show_not_updatable = True
76 break
78 if show_warning:
79 layout.label(text=WARNING, icon='ERROR')
81 if show_not_updatable:
82 layout.label(text="WARNING: This metarig contains deprecated rigify rig-types and cannot be upgraded automatically.", icon='ERROR')
83 layout.label(text="If you want to use it anyway try enabling the legacy mode before generating again.")
85 layout.operator("pose.rigify_switch_to_legacy", text="Switch to Legacy")
87 enable_generate_and_advanced = not (show_not_updatable or show_update_metarig)
89 if show_update_metarig:
91 layout.label(text="This metarig contains old rig-types that can be automatically upgraded to benefit of rigify's new features.", icon='ERROR')
92 layout.label(text= "To use it as-is you need to enable legacy mode.",)
93 layout.operator("pose.rigify_upgrade_types", text="Upgrade Metarig")
95 row = layout.row()
96 row.operator("pose.rigify_generate", text="Generate Rig", icon='POSE_HLT')
97 row.enabled = enable_generate_and_advanced
99 if id_store.rigify_advanced_generation:
100 icon = 'UNLOCKED'
101 else:
102 icon = 'LOCKED'
104 col = layout.column()
105 col.enabled = enable_generate_and_advanced
106 row = col.row()
107 row.prop(id_store, "rigify_advanced_generation", toggle=True, icon=icon)
109 if id_store.rigify_advanced_generation:
111 row = col.row(align=True)
112 row.prop(id_store, "rigify_generate_mode", expand=True)
114 main_row = col.row(align=True).split(percentage=0.3)
115 col1 = main_row.column()
116 col2 = main_row.column()
117 col1.label(text="Rig Name")
118 row = col1.row()
119 row.label(text="Target Rig")
120 row.enabled = (id_store.rigify_generate_mode == "overwrite")
121 row = col1.row()
122 row.label(text="Target UI")
123 row.enabled = (id_store.rigify_generate_mode == "overwrite")
125 row = col2.row(align=True)
126 row.prop(id_store, "rigify_rig_basename", text="", icon="SORTALPHA")
128 row = col2.row(align=True)
129 for i in range(0, len(id_store.rigify_target_rigs)):
130 id_store.rigify_target_rigs.remove(0)
132 for ob in context.scene.objects:
133 if type(ob.data) == bpy.types.Armature and "rig_id" in ob.data:
134 id_store.rigify_target_rigs.add()
135 id_store.rigify_target_rigs[-1].name = ob.name
137 row.prop_search(id_store, "rigify_target_rig", id_store, "rigify_target_rigs", text="",
138 icon='OUTLINER_OB_ARMATURE')
139 row.enabled = (id_store.rigify_generate_mode == "overwrite")
141 for i in range(0, len(id_store.rigify_rig_uis)):
142 id_store.rigify_rig_uis.remove(0)
144 for t in bpy.data.texts:
145 id_store.rigify_rig_uis.add()
146 id_store.rigify_rig_uis[-1].name = t.name
148 row = col2.row()
149 row.prop_search(id_store, "rigify_rig_ui", id_store, "rigify_rig_uis", text="", icon='TEXT')
150 row.enabled = (id_store.rigify_generate_mode == "overwrite")
152 row = col.row()
153 row.prop(id_store, "rigify_force_widget_update")
154 if id_store.rigify_generate_mode == 'new':
155 row.enabled = False
157 elif obj.mode == 'EDIT':
158 # Build types list
159 collection_name = str(id_store.rigify_collection).replace(" ", "")
161 for i in range(0, len(id_store.rigify_types)):
162 id_store.rigify_types.remove(0)
164 for r in rig_lists.rig_list:
166 if collection_name == "All":
167 a = id_store.rigify_types.add()
168 a.name = r
169 elif r.startswith(collection_name + '.'):
170 a = id_store.rigify_types.add()
171 a.name = r
172 elif (collection_name == "None") and ("." not in r):
173 a = id_store.rigify_types.add()
174 a.name = r
176 # Rig type list
177 row = layout.row()
178 row.template_list("UI_UL_list", "rigify_types", id_store, "rigify_types", id_store, 'rigify_active_type')
180 props = layout.operator("armature.metarig_sample_add", text="Add sample")
181 props.metarig_type = id_store.rigify_types[id_store.rigify_active_type].name
184 class DATA_PT_rigify_layer_names(bpy.types.Panel):
185 bl_label = "Rigify Layer Names"
186 bl_space_type = 'PROPERTIES'
187 bl_region_type = 'WINDOW'
188 bl_context = "data"
189 bl_options = {'DEFAULT_CLOSED'}
191 @classmethod
192 def poll(cls, context):
193 return context.object.type == 'ARMATURE' and context.active_object.data.get("rig_id") is None
195 def draw(self, context):
196 layout = self.layout
197 obj = context.object
198 arm = obj.data
200 # Ensure that the layers exist
201 if 0:
202 for i in range(1 + len(arm.rigify_layers), 29):
203 arm.rigify_layers.add()
204 else:
205 # Can't add while drawing, just use button
206 if len(arm.rigify_layers) < 29:
207 layout.operator("pose.rigify_layer_init")
208 return
210 # UI
211 main_row = layout.row(align=True).split(0.05)
212 col1 = main_row.column()
213 col2 = main_row.column()
214 col1.label()
215 for i in range(32):
216 if i == 16 or i == 29:
217 col1.label()
218 col1.label(str(i+1) + '.')
220 for i, rigify_layer in enumerate(arm.rigify_layers):
221 # note: rigify_layer == arm.rigify_layers[i]
222 if (i % 16) == 0:
223 col = col2.column()
224 if i == 0:
225 col.label(text="Top Row:")
226 else:
227 col.label(text="Bottom Row:")
228 if (i % 8) == 0:
229 col = col2.column()
230 if i != 28:
231 row = col.row(align=True)
232 icon = 'RESTRICT_VIEW_OFF' if arm.layers[i] else 'RESTRICT_VIEW_ON'
233 row.prop(arm, "layers", index=i, text="", toggle=True, icon=icon)
234 #row.prop(arm, "layers", index=i, text="Layer %d" % (i + 1), toggle=True, icon=icon)
235 row.prop(rigify_layer, "name", text="")
236 row.prop(rigify_layer, "row", text="UI Row")
237 icon = 'RADIOBUT_ON' if rigify_layer.set else 'RADIOBUT_OFF'
238 row.prop(rigify_layer, "set", text="", toggle=True, icon=icon)
239 row.prop(rigify_layer, "group", text="Bone Group")
240 else:
241 row = col.row(align=True)
243 icon = 'RESTRICT_VIEW_OFF' if arm.layers[i] else 'RESTRICT_VIEW_ON'
244 row.prop(arm, "layers", index=i, text="", toggle=True, icon=icon)
245 # row.prop(arm, "layers", index=i, text="Layer %d" % (i + 1), toggle=True, icon=icon)
246 row1 = row.split(align=True).row(align=True)
247 row1.prop(rigify_layer, "name", text="")
248 row1.prop(rigify_layer, "row", text="UI Row")
249 row1.enabled = False
250 icon = 'RADIOBUT_ON' if rigify_layer.set else 'RADIOBUT_OFF'
251 row.prop(rigify_layer, "set", text="", toggle=True, icon=icon)
252 row.prop(rigify_layer, "group", text="Bone Group")
253 if rigify_layer.group == 0:
254 row.label(text='None')
255 else:
256 row.label(text=arm.rigify_colors[rigify_layer.group-1].name)
258 col = col2.column()
259 col.label(text="Reserved:")
260 # reserved_names = {28: 'Root', 29: 'DEF', 30: 'MCH', 31: 'ORG'}
261 reserved_names = {29: 'DEF', 30: 'MCH', 31: 'ORG'}
262 # for i in range(28, 32):
263 for i in range(29, 32):
264 row = col.row(align=True)
265 icon = 'RESTRICT_VIEW_OFF' if arm.layers[i] else 'RESTRICT_VIEW_ON'
266 row.prop(arm, "layers", index=i, text="", toggle=True, icon=icon)
267 row.label(text=reserved_names[i])
270 class DATA_OT_rigify_add_bone_groups(bpy.types.Operator):
271 bl_idname = "armature.rigify_add_bone_groups"
272 bl_label = "Rigify Add Standard Bone Groups"
274 @classmethod
275 def poll(cls, context):
276 return context.object.type == 'ARMATURE'
278 def execute(self, context):
279 obj = context.object
280 armature = obj.data
281 if not hasattr(armature, 'rigify_colors'):
282 return {'FINISHED'}
284 groups = ['Root', 'IK', 'Special', 'Tweak', 'FK', 'Extra']
286 for g in groups:
287 if g in armature.rigify_colors.keys():
288 continue
290 armature.rigify_colors.add()
291 armature.rigify_colors[-1].name = g
293 armature.rigify_colors[g].select = Color((0.3140000104904175, 0.7839999794960022, 1.0))
294 armature.rigify_colors[g].active = Color((0.5490000247955322, 1.0, 1.0))
295 armature.rigify_colors[g].standard_colors_lock = True
297 if g == "Root":
298 armature.rigify_colors[g].normal = Color((0.43529415130615234, 0.18431372940540314, 0.41568630933761597))
299 if g == "IK":
300 armature.rigify_colors[g].normal = Color((0.6039215922355652, 0.0, 0.0))
301 if g== "Special":
302 armature.rigify_colors[g].normal = Color((0.9568628072738647, 0.7882353663444519, 0.0470588281750679))
303 if g== "Tweak":
304 armature.rigify_colors[g].normal = Color((0.03921568766236305, 0.21176472306251526, 0.5803921818733215))
305 if g== "FK":
306 armature.rigify_colors[g].normal = Color((0.11764706671237946, 0.5686274766921997, 0.03529411926865578))
307 if g== "Extra":
308 armature.rigify_colors[g].normal = Color((0.9686275124549866, 0.250980406999588, 0.0941176563501358))
310 return {'FINISHED'}
313 class DATA_OT_rigify_use_standard_colors(bpy.types.Operator):
314 bl_idname = "armature.rigify_use_standard_colors"
315 bl_label = "Rigify Get active/select colors from current theme"
317 @classmethod
318 def poll(cls, context):
319 return context.object.type == 'ARMATURE'
321 def execute(self, context):
322 obj = context.object
323 armature = obj.data
324 if not hasattr(armature, 'rigify_colors'):
325 return {'FINISHED'}
327 current_theme = bpy.context.user_preferences.themes.items()[0][0]
328 theme = bpy.context.user_preferences.themes[current_theme]
330 armature.rigify_selection_colors.select = theme.view_3d.bone_pose
331 armature.rigify_selection_colors.active = theme.view_3d.bone_pose_active
333 # for col in armature.rigify_colors:
334 # col.select = theme.view_3d.bone_pose
335 # col.active = theme.view_3d.bone_pose_active
337 return {'FINISHED'}
340 class DATA_OT_rigify_apply_selection_colors(bpy.types.Operator):
341 bl_idname = "armature.rigify_apply_selection_colors"
342 bl_label = "Rigify Apply user defined active/select colors"
344 @classmethod
345 def poll(cls, context):
346 return context.object.type == 'ARMATURE'
348 def execute(self, context):
349 obj = context.object
350 armature = obj.data
351 if not hasattr(armature, 'rigify_colors'):
352 return {'FINISHED'}
354 #current_theme = bpy.context.user_preferences.themes.items()[0][0]
355 #theme = bpy.context.user_preferences.themes[current_theme]
357 for col in armature.rigify_colors:
358 col.select = armature.rigify_selection_colors.select
359 col.active = armature.rigify_selection_colors.active
361 return {'FINISHED'}
364 class DATA_OT_rigify_bone_group_add(bpy.types.Operator):
365 bl_idname = "armature.rigify_bone_group_add"
366 bl_label = "Rigify Add Bone Group color set"
368 @classmethod
369 def poll(cls, context):
370 return context.object.type == 'ARMATURE'
372 def execute(self, context):
373 obj = context.object
374 armature = obj.data
376 if hasattr(armature, 'rigify_colors'):
377 armature.rigify_colors.add()
378 armature.rigify_colors[-1].name = unique_name(armature.rigify_colors, 'Group')
380 current_theme = bpy.context.user_preferences.themes.items()[0][0]
381 theme = bpy.context.user_preferences.themes[current_theme]
383 armature.rigify_colors[-1].normal = theme.view_3d.wire
384 armature.rigify_colors[-1].normal.hsv = theme.view_3d.wire.hsv
385 armature.rigify_colors[-1].select = theme.view_3d.bone_pose
386 armature.rigify_colors[-1].select.hsv = theme.view_3d.bone_pose.hsv
387 armature.rigify_colors[-1].active = theme.view_3d.bone_pose_active
388 armature.rigify_colors[-1].active.hsv = theme.view_3d.bone_pose_active.hsv
390 return {'FINISHED'}
393 class DATA_OT_rigify_bone_group_add_theme(bpy.types.Operator):
394 bl_idname = "armature.rigify_bone_group_add_theme"
395 bl_label = "Rigify Add Bone Group color set from Theme"
396 bl_options = {"REGISTER", "UNDO"}
398 theme = bpy.props.EnumProperty(items=(('THEME01', 'THEME01', ''),
399 ('THEME02', 'THEME02', ''),
400 ('THEME03', 'THEME03', ''),
401 ('THEME04', 'THEME04', ''),
402 ('THEME05', 'THEME05', ''),
403 ('THEME06', 'THEME06', ''),
404 ('THEME07', 'THEME07', ''),
405 ('THEME08', 'THEME08', ''),
406 ('THEME09', 'THEME09', ''),
407 ('THEME10', 'THEME10', ''),
408 ('THEME11', 'THEME11', ''),
409 ('THEME12', 'THEME12', ''),
410 ('THEME13', 'THEME13', ''),
411 ('THEME14', 'THEME14', ''),
412 ('THEME15', 'THEME15', ''),
413 ('THEME16', 'THEME16', ''),
414 ('THEME17', 'THEME17', ''),
415 ('THEME18', 'THEME18', ''),
416 ('THEME19', 'THEME19', ''),
417 ('THEME20', 'THEME20', '')
419 name='Theme')
421 @classmethod
422 def poll(cls, context):
423 return context.object.type == 'ARMATURE'
425 def execute(self, context):
426 obj = context.object
427 armature = obj.data
429 if hasattr(armature, 'rigify_colors'):
431 if self.theme in armature.rigify_colors.keys():
432 return {'FINISHED'}
433 armature.rigify_colors.add()
434 armature.rigify_colors[-1].name = self.theme
436 id = int(self.theme[-2:]) - 1
438 theme_color_set = bpy.context.user_preferences.themes[0].bone_color_sets[id]
440 armature.rigify_colors[-1].normal = theme_color_set.normal
441 armature.rigify_colors[-1].select = theme_color_set.select
442 armature.rigify_colors[-1].active = theme_color_set.active
444 return {'FINISHED'}
447 class DATA_OT_rigify_bone_group_remove(bpy.types.Operator):
448 bl_idname = "armature.rigify_bone_group_remove"
449 bl_label = "Rigify Remove Bone Group color set"
451 idx = bpy.props.IntProperty()
453 @classmethod
454 def poll(cls, context):
455 return context.object.type == 'ARMATURE'
457 def execute(self, context):
458 obj = context.object
459 obj.data.rigify_colors.remove(self.idx)
461 # set layers references to 0
462 for l in obj.data.rigify_layers:
463 if l.group == self.idx + 1:
464 l.group = 0
465 elif l.group > self.idx + 1:
466 l.group -= 1
468 return {'FINISHED'}
471 class DATA_OT_rigify_bone_group_remove_all(bpy.types.Operator):
472 bl_idname = "armature.rigify_bone_group_remove_all"
473 bl_label = "Rigify Remove All Bone Groups"
475 @classmethod
476 def poll(cls, context):
477 return context.object.type == 'ARMATURE'
479 def execute(self, context):
480 obj = context.object
482 for i, col in enumerate(obj.data.rigify_colors):
483 obj.data.rigify_colors.remove(0)
484 # set layers references to 0
485 for l in obj.data.rigify_layers:
486 if l.group == i + 1:
487 l.group = 0
489 return {'FINISHED'}
492 class DATA_UL_rigify_bone_groups(bpy.types.UIList):
493 def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
494 row = layout.row(align=True)
495 row = row.split(percentage=0.1)
496 row.label(text=str(index+1))
497 row = row.split(percentage=0.7)
498 row.prop(item, "name", text='', emboss=False)
499 row = row.row(align=True)
500 icon = 'LOCKED' if item.standard_colors_lock else 'UNLOCKED'
501 #row.prop(item, "standard_colors_lock", text='', icon=icon)
502 row.prop(item, "normal", text='')
503 row2 = row.row(align=True)
504 row2.prop(item, "select", text='')
505 row2.prop(item, "active", text='')
506 #row2.enabled = not item.standard_colors_lock
507 row2.enabled = not bpy.context.object.data.rigify_colors_lock
510 class DATA_MT_rigify_bone_groups_specials(bpy.types.Menu):
511 bl_label = 'Rigify Bone Groups Specials'
513 def draw(self, context):
514 layout = self.layout
516 layout.operator('armature.rigify_bone_group_remove_all')
519 class DATA_PT_rigify_bone_groups(bpy.types.Panel):
520 bl_label = "Rigify Bone Groups"
521 bl_space_type = 'PROPERTIES'
522 bl_region_type = 'WINDOW'
523 bl_context = "data"
524 bl_options = {'DEFAULT_CLOSED'}
526 @classmethod
527 def poll(cls, context):
528 return context.object.type == 'ARMATURE' and context.active_object.data.get("rig_id") is None
530 def draw(self, context):
531 obj = context.object
532 armature = obj.data
533 color_sets = obj.data.rigify_colors
534 idx = obj.data.rigify_colors_index
536 layout = self.layout
537 row = layout.row()
538 row.operator("armature.rigify_use_standard_colors", icon='FILE_REFRESH', text='')
539 row = row.row(align=True)
540 row.prop(armature.rigify_selection_colors, 'select', text='')
541 row.prop(armature.rigify_selection_colors, 'active', text='')
542 row = layout.row(align=True)
543 icon = 'LOCKED' if armature.rigify_colors_lock else 'UNLOCKED'
544 row.prop(armature, 'rigify_colors_lock', text = 'Unified select/active colors', icon=icon)
545 row.operator("armature.rigify_apply_selection_colors", icon='FILE_REFRESH', text='Apply')
546 row = layout.row()
547 row.template_list("DATA_UL_rigify_bone_groups", "", obj.data, "rigify_colors", obj.data, "rigify_colors_index")
549 col = row.column(align=True)
550 col.operator("armature.rigify_bone_group_add", icon='ZOOMIN', text="")
551 col.operator("armature.rigify_bone_group_remove", icon='ZOOMOUT', text="").idx = obj.data.rigify_colors_index
552 col.menu("DATA_MT_rigify_bone_groups_specials", icon='DOWNARROW_HLT', text="")
553 row = layout.row()
554 row.prop(armature, 'rigify_theme_to_add', text = 'Theme')
555 op = row.operator("armature.rigify_bone_group_add_theme", text="Add From Theme")
556 op.theme = armature.rigify_theme_to_add
557 row = layout.row()
558 row.operator("armature.rigify_add_bone_groups", text="Add Standard")
561 class BONE_PT_rigify_buttons(bpy.types.Panel):
562 bl_label = "Rigify Type"
563 bl_space_type = 'PROPERTIES'
564 bl_region_type = 'WINDOW'
565 bl_context = "bone"
566 #bl_options = {'DEFAULT_OPEN'}
568 @classmethod
569 def poll(cls, context):
571 return context.object.type == 'ARMATURE' and context.active_pose_bone\
572 and context.active_object.data.get("rig_id") is None
574 def draw(self, context):
575 C = context
576 id_store = C.window_manager
577 bone = context.active_pose_bone
578 collection_name = str(id_store.rigify_collection).replace(" ", "")
579 rig_name = str(context.active_pose_bone.rigify_type).replace(" ", "")
581 layout = self.layout
583 # Build types list
584 for i in range(0, len(id_store.rigify_types)):
585 id_store.rigify_types.remove(0)
587 for r in rig_lists.rig_list:
588 if r in rig_lists.implementation_rigs:
589 continue
590 # collection = r.split('.')[0] # UNUSED
591 if collection_name == "All":
592 a = id_store.rigify_types.add()
593 a.name = r
594 elif r.startswith(collection_name + '.'):
595 a = id_store.rigify_types.add()
596 a.name = r
597 elif collection_name == "None" and len(r.split('.')) == 1:
598 a = id_store.rigify_types.add()
599 a.name = r
601 # Rig type field
602 row = layout.row()
603 row.prop_search(bone, "rigify_type", id_store, "rigify_types", text="Rig type:")
605 # Rig type parameters / Rig type non-exist alert
606 if rig_name != "":
607 try:
608 rig = get_rig_type(rig_name)
609 rig.Rig
610 except (ImportError, AttributeError):
611 row = layout.row()
612 box = row.box()
613 box.label(text="ALERT: type \"%s\" does not exist!" % rig_name)
614 else:
615 try:
616 rig.parameters_ui
617 except AttributeError:
618 col = layout.column()
619 col.label(text="No options")
620 else:
621 col = layout.column()
622 col.label(text="Options:")
623 box = layout.box()
624 rig.parameters_ui(box, bone.rigify_parameters)
627 class VIEW3D_PT_tools_rigify_dev(bpy.types.Panel):
628 bl_label = "Rigify Dev Tools"
629 bl_category = 'Tools'
630 bl_context = "armature_edit"
631 bl_space_type = 'VIEW_3D'
632 bl_region_type = 'TOOLS'
634 def draw(self, context):
635 obj = context.active_object
636 if obj is not None:
637 if context.mode == 'EDIT_ARMATURE':
638 r = self.layout.row()
639 r.operator("armature.rigify_encode_metarig", text="Encode Metarig to Python")
640 r = self.layout.row()
641 r.operator("armature.rigify_encode_metarig_sample", text="Encode Sample to Python")
643 if context.mode == 'EDIT_MESH':
644 r = self.layout.row()
645 r.operator("mesh.rigify_encode_mesh_widget", text="Encode Mesh Widget to Python")
648 class VIEW3D_PT_rigify_animation_tools(bpy.types.Panel):
649 bl_label = "Rigify Animation Tools"
650 bl_category = 'Tools'
651 bl_context = "posemode"
652 bl_space_type = 'VIEW_3D'
653 bl_region_type = 'TOOLS'
655 @classmethod
656 def poll(cls, context):
657 return context.object.type == 'ARMATURE' and context.active_object.data.get("rig_id") is not None
659 def draw(self, context):
660 obj = context.active_object
661 id_store = context.window_manager
662 if obj is not None:
663 row = self.layout.row()
665 if id_store.rigify_transfer_only_selected:
666 icon = 'OUTLINER_DATA_ARMATURE'
667 else:
668 icon = 'ARMATURE_DATA'
670 row.prop(id_store, 'rigify_transfer_only_selected', toggle=True, icon=icon)
672 row = self.layout.row(align=True)
673 row.operator("rigify.ik2fk", text='IK2FK Pose', icon='SNAP_ON')
674 row.operator("rigify.fk2ik", text='FK2IK Pose', icon='SNAP_ON')
676 row = self.layout.row(align=True)
677 row.operator("rigify.transfer_fk_to_ik", text='IK2FK Action', icon='ACTION_TWEAK')
678 row.operator("rigify.transfer_ik_to_fk", text='FK2IK Action', icon='ACTION_TWEAK')
680 row = self.layout.row(align=True)
681 row.operator("rigify.clear_animation", text="Clear IK Action", icon='CANCEL').type = "IK"
682 row.operator("rigify.clear_animation", text="Clear FK Action", icon='CANCEL').type = "FK"
684 row = self.layout.row(align=True)
685 op = row.operator("rigify.rotation_pole", icon='FORCE_HARMONIC', text='Switch to pole')
686 op.value = True
687 op.toggle = False
688 op.bake = True
689 op = row.operator("rigify.rotation_pole", icon='FORCE_MAGNETIC', text='Switch to rotation')
690 op.value = False
691 op.toggle = False
692 op.bake = True
693 row = self.layout.row(align=True)
694 row.prop(id_store, 'rigify_transfer_start_frame')
695 row.prop(id_store, 'rigify_transfer_end_frame')
696 row.operator("rigify.get_frame_range", icon='TIME', text='')
699 def rigify_report_exception(operator, exception):
700 import traceback
701 import sys
702 import os
703 # find the module name where the error happened
704 # hint, this is the metarig type!
705 exceptionType, exceptionValue, exceptionTraceback = sys.exc_info()
706 fn = traceback.extract_tb(exceptionTraceback)[-1][0]
707 fn = os.path.basename(fn)
708 fn = os.path.splitext(fn)[0]
709 message = []
710 if fn.startswith("__"):
711 message.append("Incorrect armature...")
712 else:
713 message.append("Incorrect armature for type '%s'" % fn)
714 message.append(exception.message)
716 message.reverse() # XXX - stupid! menu's are upside down!
718 operator.report({'INFO'}, '\n'.join(message))
721 class LayerInit(bpy.types.Operator):
722 """Initialize armature rigify layers"""
724 bl_idname = "pose.rigify_layer_init"
725 bl_label = "Add Rigify Layers"
726 bl_options = {'UNDO'}
728 def execute(self, context):
729 obj = context.object
730 arm = obj.data
731 for i in range(1 + len(arm.rigify_layers), 30):
732 arm.rigify_layers.add()
733 arm.rigify_layers[28].name = 'Root'
734 arm.rigify_layers[28].row = 14
735 return {'FINISHED'}
738 class Generate(bpy.types.Operator):
739 """Generates a rig from the active metarig armature"""
741 bl_idname = "pose.rigify_generate"
742 bl_label = "Rigify Generate Rig"
743 bl_options = {'UNDO'}
744 bl_description = 'Generates a rig from the active metarig armature'
746 def execute(self, context):
747 import importlib
748 importlib.reload(generate)
750 use_global_undo = context.user_preferences.edit.use_global_undo
751 context.user_preferences.edit.use_global_undo = False
752 try:
753 generate.generate_rig(context, context.object)
754 except MetarigError as rig_exception:
755 rigify_report_exception(self, rig_exception)
756 finally:
757 context.user_preferences.edit.use_global_undo = use_global_undo
759 return {'FINISHED'}
762 class UpgradeMetarigTypes(bpy.types.Operator):
763 """Upgrades metarig bones rigify_types"""
765 bl_idname = "pose.rigify_upgrade_types"
766 bl_label = "Rigify Upgrade Metarig Types"
767 bl_description = 'Upgrades the rigify types on the active metarig armature'
768 bl_options = {'UNDO'}
770 def execute(self, context):
771 for obj in bpy.data.objects:
772 if type(obj.data) == bpy.types.Armature:
773 upgradeMetarigTypes(obj)
774 return {'FINISHED'}
777 class SwitchToLegacy(bpy.types.Operator):
778 """Switch to Legacy mode"""
780 bl_idname = "pose.rigify_switch_to_legacy"
781 bl_label = "Legacy Mode will disable Rigify new features"
782 bl_description = 'Switches Rigify to Legacy Mode'
783 bl_options = {'UNDO'}
785 def invoke(self, context, event):
786 return context.window_manager.invoke_confirm(self, event)
788 def execute(self, context):
789 bpy.context.user_preferences.addons['rigify'].preferences.legacy_mode = True
790 return {'FINISHED'}
793 class Sample(bpy.types.Operator):
794 """Create a sample metarig to be modified before generating """ \
795 """the final rig"""
797 bl_idname = "armature.metarig_sample_add"
798 bl_label = "Add a sample metarig for a rig type"
799 bl_options = {'UNDO'}
801 metarig_type = StringProperty(
802 name="Type",
803 description="Name of the rig type to generate a sample of",
804 maxlen=128,
807 def execute(self, context):
808 if context.mode == 'EDIT_ARMATURE' and self.metarig_type != "":
809 use_global_undo = context.user_preferences.edit.use_global_undo
810 context.user_preferences.edit.use_global_undo = False
811 try:
812 rig = get_rig_type(self.metarig_type)
813 create_sample = rig.create_sample
814 except (ImportError, AttributeError):
815 raise Exception("rig type '" + self.metarig_type + "' has no sample.")
816 else:
817 create_sample(context.active_object)
818 finally:
819 context.user_preferences.edit.use_global_undo = use_global_undo
820 bpy.ops.object.mode_set(mode='EDIT')
822 return {'FINISHED'}
825 class EncodeMetarig(bpy.types.Operator):
826 """ Creates Python code that will generate the selected metarig.
828 bl_idname = "armature.rigify_encode_metarig"
829 bl_label = "Rigify Encode Metarig"
830 bl_options = {'UNDO'}
832 @classmethod
833 def poll(self, context):
834 return context.mode == 'EDIT_ARMATURE'
836 def execute(self, context):
837 name = "metarig.py"
839 if name in bpy.data.texts:
840 text_block = bpy.data.texts[name]
841 text_block.clear()
842 else:
843 text_block = bpy.data.texts.new(name)
845 text = write_metarig(context.active_object, layers=True, func_name="create", groups=True)
846 text_block.write(text)
847 bpy.ops.object.mode_set(mode='EDIT')
849 return {'FINISHED'}
852 class EncodeMetarigSample(bpy.types.Operator):
853 """ Creates Python code that will generate the selected metarig
854 as a sample.
856 bl_idname = "armature.rigify_encode_metarig_sample"
857 bl_label = "Rigify Encode Metarig Sample"
858 bl_options = {'UNDO'}
860 @classmethod
861 def poll(self, context):
862 return context.mode == 'EDIT_ARMATURE'
864 def execute(self, context):
865 name = "metarig_sample.py"
867 if name in bpy.data.texts:
868 text_block = bpy.data.texts[name]
869 text_block.clear()
870 else:
871 text_block = bpy.data.texts.new(name)
873 text = write_metarig(context.active_object, layers=False, func_name="create_sample")
874 text_block.write(text)
875 bpy.ops.object.mode_set(mode='EDIT')
877 return {'FINISHED'}
880 class EncodeWidget(bpy.types.Operator):
881 """ Creates Python code that will generate the selected metarig.
883 bl_idname = "mesh.rigify_encode_mesh_widget"
884 bl_label = "Rigify Encode Widget"
885 bl_options = {'UNDO'}
887 @classmethod
888 def poll(self, context):
889 return context.mode == 'EDIT_MESH'
891 def execute(self, context):
892 name = "widget.py"
894 if name in bpy.data.texts:
895 text_block = bpy.data.texts[name]
896 text_block.clear()
897 else:
898 text_block = bpy.data.texts.new(name)
900 text = write_widget(context.active_object)
901 text_block.write(text)
902 bpy.ops.object.mode_set(mode='EDIT')
904 return {'FINISHED'}
907 class OBJECT_OT_GetFrameRange(bpy.types.Operator):
908 """Get start and end frame range"""
909 bl_idname = "rigify.get_frame_range"
910 bl_label = "Get Frame Range"
912 def execute(self, context):
913 scn = context.scene
914 id_store = context.window_manager
916 id_store.rigify_transfer_start_frame = scn.frame_start
917 id_store.rigify_transfer_end_frame = scn.frame_end
919 return {'FINISHED'}
922 def FktoIk(rig, window='ALL'):
924 scn = bpy.context.scene
925 id_store = bpy.context.window_manager
927 rig_id = rig.data['rig_id']
928 leg_ik2fk = eval('bpy.ops.pose.rigify_leg_ik2fk_' + rig_id)
929 arm_ik2fk = eval('bpy.ops.pose.rigify_arm_ik2fk_' + rig_id)
930 limb_generated_names = get_limb_generated_names(rig)
932 if window == 'ALL':
933 frames = get_keyed_frames(rig)
934 frames = [f for f in frames if f in range(id_store.rigify_transfer_start_frame, id_store.rigify_transfer_end_frame+1)]
935 elif window == 'CURRENT':
936 frames = [scn.frame_current]
937 else:
938 frames = [scn.frame_current]
940 if not id_store.rigify_transfer_only_selected:
941 pbones = rig.pose.bones
942 bpy.ops.pose.select_all(action='DESELECT')
943 else:
944 pbones = bpy.context.selected_pose_bones
945 bpy.ops.pose.select_all(action='DESELECT')
947 for b in pbones:
948 for group in limb_generated_names:
949 if b.name in limb_generated_names[group].values() or b.name in limb_generated_names[group]['controls']\
950 or b.name in limb_generated_names[group]['ik_ctrl']:
951 names = limb_generated_names[group]
952 if names['limb_type'] == 'arm':
953 func = arm_ik2fk
954 controls = names['controls']
955 ik_ctrl = names['ik_ctrl']
956 fk_ctrl = names['fk_ctrl']
957 parent = names['parent']
958 pole = names['pole']
959 rig.pose.bones[controls[0]].bone.select = True
960 rig.pose.bones[controls[4]].bone.select = True
961 rig.pose.bones[pole].bone.select = True
962 rig.pose.bones[parent].bone.select = True
963 kwargs = {'uarm_fk': controls[1], 'farm_fk': controls[2], 'hand_fk': controls[3],
964 'uarm_ik': controls[0], 'farm_ik': ik_ctrl[1], 'hand_ik': controls[4],
965 'pole': pole, 'main_parent': parent}
966 args = (controls[0], controls[1], controls[2], controls[3],
967 controls[4], pole, parent)
968 else:
969 func = leg_ik2fk
970 controls = names['controls']
971 ik_ctrl = names['ik_ctrl']
972 fk_ctrl = names['fk_ctrl']
973 parent = names['parent']
974 pole = names['pole']
975 rig.pose.bones[controls[0]].bone.select = True
976 rig.pose.bones[controls[6]].bone.select = True
977 rig.pose.bones[controls[5]].bone.select = True
978 rig.pose.bones[pole].bone.select = True
979 rig.pose.bones[parent].bone.select = True
980 kwargs = {'thigh_fk': controls[1], 'shin_fk': controls[2], 'foot_fk': controls[3],
981 'mfoot_fk': controls[7], 'thigh_ik': controls[0], 'shin_ik': ik_ctrl[1],
982 'foot_ik': controls[6], 'pole': pole, 'footroll': controls[5], 'mfoot_ik': ik_ctrl[2],
983 'main_parent': parent}
984 args = (controls[0], controls[1], controls[2], controls[3],
985 controls[6], controls[5], pole, parent)
987 for f in frames:
988 if not bones_in_frame(f, rig, *args):
989 continue
990 scn.frame_set(f)
991 func(**kwargs)
992 bpy.ops.anim.keyframe_insert_menu(type='BUILTIN_KSI_VisualLocRot')
993 bpy.ops.anim.keyframe_insert_menu(type='Scaling')
995 bpy.ops.pose.select_all(action='DESELECT')
996 limb_generated_names.pop(group)
997 break
1000 def IktoFk(rig, window='ALL'):
1002 scn = bpy.context.scene
1003 id_store = bpy.context.window_manager
1005 rig_id = rig.data['rig_id']
1006 leg_fk2ik = eval('bpy.ops.pose.rigify_leg_fk2ik_' + rig_id)
1007 arm_fk2ik = eval('bpy.ops.pose.rigify_arm_fk2ik_' + rig_id)
1008 limb_generated_names = get_limb_generated_names(rig)
1010 if window == 'ALL':
1011 frames = get_keyed_frames(rig)
1012 frames = [f for f in frames if f in range(id_store.rigify_transfer_start_frame, id_store.rigify_transfer_end_frame+1)]
1013 elif window == 'CURRENT':
1014 frames = [scn.frame_current]
1015 else:
1016 frames = [scn.frame_current]
1018 if not id_store.rigify_transfer_only_selected:
1019 bpy.ops.pose.select_all(action='DESELECT')
1020 pbones = rig.pose.bones
1021 else:
1022 pbones = bpy.context.selected_pose_bones
1023 bpy.ops.pose.select_all(action='DESELECT')
1025 for b in pbones:
1026 for group in limb_generated_names:
1027 if b.name in limb_generated_names[group].values() or b.name in limb_generated_names[group]['controls']\
1028 or b.name in limb_generated_names[group]['ik_ctrl']:
1029 names = limb_generated_names[group]
1030 if names['limb_type'] == 'arm':
1031 func = arm_fk2ik
1032 controls = names['controls']
1033 ik_ctrl = names['ik_ctrl']
1034 fk_ctrl = names['fk_ctrl']
1035 parent = names['parent']
1036 pole = names['pole']
1037 rig.pose.bones[controls[1]].bone.select = True
1038 rig.pose.bones[controls[2]].bone.select = True
1039 rig.pose.bones[controls[3]].bone.select = True
1040 kwargs = {'uarm_fk': controls[1], 'farm_fk': controls[2], 'hand_fk': controls[3],
1041 'uarm_ik': controls[0], 'farm_ik': ik_ctrl[1],
1042 'hand_ik': controls[4]}
1043 args = (controls[0], controls[1], controls[2], controls[3],
1044 controls[4], pole, parent)
1045 else:
1046 func = leg_fk2ik
1047 controls = names['controls']
1048 ik_ctrl = names['ik_ctrl']
1049 fk_ctrl = names['fk_ctrl']
1050 parent = names['parent']
1051 pole = names['pole']
1052 rig.pose.bones[controls[1]].bone.select = True
1053 rig.pose.bones[controls[2]].bone.select = True
1054 rig.pose.bones[controls[3]].bone.select = True
1055 kwargs = {'thigh_fk': controls[1], 'shin_fk': controls[2], 'foot_fk': controls[3],
1056 'mfoot_fk': controls[7], 'thigh_ik': controls[0], 'shin_ik': ik_ctrl[1],
1057 'foot_ik': ik_ctrl[2], 'mfoot_ik': ik_ctrl[2]}
1058 args = (controls[0], controls[1], controls[2], controls[3],
1059 controls[6], controls[5], pole, parent)
1061 for f in frames:
1062 if not bones_in_frame(f, rig, *args):
1063 continue
1064 scn.frame_set(f)
1065 func(**kwargs)
1066 bpy.ops.anim.keyframe_insert_menu(type='BUILTIN_KSI_VisualLocRot')
1067 bpy.ops.anim.keyframe_insert_menu(type='Scaling')
1069 bpy.ops.pose.select_all(action='DESELECT')
1070 limb_generated_names.pop(group)
1071 break
1074 def clearAnimation(act, type, names):
1076 bones = []
1077 for group in names:
1078 if names[group]['limb_type'] == 'arm':
1079 if type == 'IK':
1080 bones.extend([names[group]['controls'][0], names[group]['controls'][4]])
1081 elif type == 'FK':
1082 bones.extend([names[group]['controls'][1], names[group]['controls'][2], names[group]['controls'][3]])
1083 else:
1084 if type == 'IK':
1085 bones.extend([names[group]['controls'][0], names[group]['controls'][6], names[group]['controls'][5],
1086 names[group]['controls'][4]])
1087 elif type == 'FK':
1088 bones.extend([names[group]['controls'][1], names[group]['controls'][2], names[group]['controls'][3],
1089 names[group]['controls'][4]])
1090 FCurves = []
1091 for fcu in act.fcurves:
1092 words = fcu.data_path.split('"')
1093 if (words[0] == "pose.bones[" and
1094 words[1] in bones):
1095 FCurves.append(fcu)
1097 if FCurves == []:
1098 return
1100 for fcu in FCurves:
1101 act.fcurves.remove(fcu)
1103 # Put cleared bones back to rest pose
1104 bpy.ops.pose.loc_clear()
1105 bpy.ops.pose.rot_clear()
1106 bpy.ops.pose.scale_clear()
1108 # updateView3D()
1111 def rotPoleToggle(rig, window='ALL', value=False, toggle=False, bake=False):
1113 scn = bpy.context.scene
1114 id_store = bpy.context.window_manager
1116 rig_id = rig.data['rig_id']
1117 leg_fk2ik = eval('bpy.ops.pose.rigify_leg_fk2ik_' + rig_id)
1118 arm_fk2ik = eval('bpy.ops.pose.rigify_arm_fk2ik_' + rig_id)
1119 leg_ik2fk = eval('bpy.ops.pose.rigify_leg_ik2fk_' + rig_id)
1120 arm_ik2fk = eval('bpy.ops.pose.rigify_arm_ik2fk_' + rig_id)
1121 limb_generated_names = get_limb_generated_names(rig)
1123 if window == 'ALL':
1124 frames = get_keyed_frames(rig)
1125 frames = [f for f in frames if f in range(id_store.rigify_transfer_start_frame, id_store.rigify_transfer_end_frame+1)]
1126 elif window == 'CURRENT':
1127 frames = [scn.frame_current]
1128 else:
1129 frames = [scn.frame_current]
1131 if not id_store.rigify_transfer_only_selected:
1132 bpy.ops.pose.select_all(action='DESELECT')
1133 pbones = rig.pose.bones
1134 else:
1135 pbones = bpy.context.selected_pose_bones
1136 bpy.ops.pose.select_all(action='DESELECT')
1138 for b in pbones:
1139 for group in limb_generated_names:
1140 names = limb_generated_names[group]
1142 if toggle:
1143 new_pole_vector_value = not rig.pose.bones[names['parent']]['pole_vector']
1144 else:
1145 new_pole_vector_value = value
1147 if b.name in names.values() or b.name in names['controls'] or b.name in names['ik_ctrl']:
1148 if names['limb_type'] == 'arm':
1149 func1 = arm_fk2ik
1150 func2 = arm_ik2fk
1151 controls = names['controls']
1152 ik_ctrl = names['ik_ctrl']
1153 fk_ctrl = names['fk_ctrl']
1154 parent = names['parent']
1155 pole = names['pole']
1156 rig.pose.bones[controls[0]].bone.select = not new_pole_vector_value
1157 rig.pose.bones[controls[4]].bone.select = not new_pole_vector_value
1158 rig.pose.bones[parent].bone.select = not new_pole_vector_value
1159 rig.pose.bones[pole].bone.select = new_pole_vector_value
1161 kwargs1 = {'uarm_fk': controls[1], 'farm_fk': controls[2], 'hand_fk': controls[3],
1162 'uarm_ik': controls[0], 'farm_ik': ik_ctrl[1],
1163 'hand_ik': controls[4]}
1164 kwargs2 = {'uarm_fk': controls[1], 'farm_fk': controls[2], 'hand_fk': controls[3],
1165 'uarm_ik': controls[0], 'farm_ik': ik_ctrl[1], 'hand_ik': controls[4],
1166 'pole': pole, 'main_parent': parent}
1167 args = (controls[0], controls[4], pole, parent)
1168 else:
1169 func1 = leg_fk2ik
1170 func2 = leg_ik2fk
1171 controls = names['controls']
1172 ik_ctrl = names['ik_ctrl']
1173 fk_ctrl = names['fk_ctrl']
1174 parent = names['parent']
1175 pole = names['pole']
1176 rig.pose.bones[controls[0]].bone.select = not new_pole_vector_value
1177 rig.pose.bones[controls[6]].bone.select = not new_pole_vector_value
1178 rig.pose.bones[controls[5]].bone.select = not new_pole_vector_value
1179 rig.pose.bones[parent].bone.select = not new_pole_vector_value
1180 rig.pose.bones[pole].bone.select = new_pole_vector_value
1182 kwargs1 = {'thigh_fk': controls[1], 'shin_fk': controls[2], 'foot_fk': controls[3],
1183 'mfoot_fk': controls[7], 'thigh_ik': controls[0], 'shin_ik': ik_ctrl[1],
1184 'foot_ik': ik_ctrl[2], 'mfoot_ik': ik_ctrl[2]}
1185 kwargs2 = {'thigh_fk': controls[1], 'shin_fk': controls[2], 'foot_fk': controls[3],
1186 'mfoot_fk': controls[7], 'thigh_ik': controls[0], 'shin_ik': ik_ctrl[1],
1187 'foot_ik': controls[6], 'pole': pole, 'footroll': controls[5], 'mfoot_ik': ik_ctrl[2],
1188 'main_parent': parent}
1189 args = (controls[0], controls[6], controls[5], pole, parent)
1191 for f in frames:
1192 if not bones_in_frame(f, rig, *args):
1193 continue
1194 scn.frame_set(f)
1195 func1(**kwargs1)
1196 rig.pose.bones[names['parent']]['pole_vector'] = new_pole_vector_value
1197 func2(**kwargs2)
1198 if bake:
1199 bpy.ops.anim.keyframe_insert_menu(type='BUILTIN_KSI_VisualLocRot')
1200 bpy.ops.anim.keyframe_insert_menu(type='Scaling')
1201 overwrite_prop_animation(rig, rig.pose.bones[parent], 'pole_vector', new_pole_vector_value, [f])
1203 bpy.ops.pose.select_all(action='DESELECT')
1204 limb_generated_names.pop(group)
1205 break
1206 scn.frame_set(0)
1209 class OBJECT_OT_IK2FK(bpy.types.Operator):
1210 """ Snaps IK limb on FK limb at current frame"""
1211 bl_idname = "rigify.ik2fk"
1212 bl_label = "IK2FK"
1213 bl_description = "Snaps IK limb on FK"
1215 def execute(self,context):
1216 rig = context.object
1217 id_store = context.window_manager
1219 FktoIk(rig, window='CURRENT')
1221 return {'FINISHED'}
1224 class OBJECT_OT_FK2IK(bpy.types.Operator):
1225 """ Snaps FK limb on IK limb at current frame"""
1226 bl_idname = "rigify.fk2ik"
1227 bl_label = "FK2IK"
1228 bl_description = "Snaps FK limb on IK"
1230 def execute(self,context):
1231 rig = context.object
1233 IktoFk(rig, window='CURRENT')
1235 return {'FINISHED'}
1238 class OBJECT_OT_TransferFKtoIK(bpy.types.Operator):
1239 """Transfers FK animation to IK"""
1240 bl_idname = "rigify.transfer_fk_to_ik"
1241 bl_label = "Transfer FK anim to IK"
1242 bl_description = "Transfer FK animation to IK bones"
1244 def execute(self, context):
1245 rig = context.object
1246 id_store = context.window_manager
1248 FktoIk(rig)
1250 return {'FINISHED'}
1253 class OBJECT_OT_TransferIKtoFK(bpy.types.Operator):
1254 """Transfers FK animation to IK"""
1255 bl_idname = "rigify.transfer_ik_to_fk"
1256 bl_label = "Transfer IK anim to FK"
1257 bl_description = "Transfer IK animation to FK bones"
1259 def execute(self, context):
1260 rig = context.object
1262 IktoFk(rig)
1264 return {'FINISHED'}
1267 class OBJECT_OT_ClearAnimation(bpy.types.Operator):
1268 bl_idname = "rigify.clear_animation"
1269 bl_label = "Clear Animation"
1270 bl_description = "Clear Animation For FK or IK Bones"
1271 type = StringProperty()
1273 def execute(self, context):
1275 use_global_undo = context.user_preferences.edit.use_global_undo
1276 context.user_preferences.edit.use_global_undo = False
1277 try:
1278 rig = context.object
1279 scn = context.scene
1280 if not rig.animation_data:
1281 return {'FINISHED'}
1282 act = rig.animation_data.action
1283 if not act:
1284 return {'FINISHED'}
1286 clearAnimation(act, self.type, names=get_limb_generated_names(rig))
1287 finally:
1288 context.user_preferences.edit.use_global_undo = use_global_undo
1289 return {'FINISHED'}
1292 class OBJECT_OT_Rot2Pole(bpy.types.Operator):
1293 bl_idname = "rigify.rotation_pole"
1294 bl_label = "Rotation - Pole toggle"
1295 bl_description = "Toggles IK chain between rotation and pole target"
1296 bone_name = bpy.props.StringProperty(default='')
1297 window = bpy.props.StringProperty(default='ALL')
1298 toggle = bpy.props.BoolProperty(default=True)
1299 value = bpy.props.BoolProperty(default=True)
1300 bake = bpy.props.BoolProperty(default=True)
1302 def execute(self, context):
1303 rig = context.object
1305 if self.bone_name:
1306 bpy.ops.pose.select_all(action='DESELECT')
1307 rig.pose.bones[self.bone_name].bone.select = True
1309 rotPoleToggle(rig, window=self.window, toggle=self.toggle, value=self.value, bake=self.bake)
1310 return {'FINISHED'}
1313 def register():
1315 bpy.utils.register_class(DATA_OT_rigify_add_bone_groups)
1316 bpy.utils.register_class(DATA_OT_rigify_use_standard_colors)
1317 bpy.utils.register_class(DATA_OT_rigify_apply_selection_colors)
1318 bpy.utils.register_class(DATA_OT_rigify_bone_group_add)
1319 bpy.utils.register_class(DATA_OT_rigify_bone_group_add_theme)
1320 bpy.utils.register_class(DATA_OT_rigify_bone_group_remove)
1321 bpy.utils.register_class(DATA_OT_rigify_bone_group_remove_all)
1322 bpy.utils.register_class(DATA_UL_rigify_bone_groups)
1323 bpy.utils.register_class(DATA_MT_rigify_bone_groups_specials)
1324 bpy.utils.register_class(DATA_PT_rigify_bone_groups)
1325 bpy.utils.register_class(DATA_PT_rigify_layer_names)
1326 bpy.utils.register_class(DATA_PT_rigify_buttons)
1327 bpy.utils.register_class(BONE_PT_rigify_buttons)
1328 bpy.utils.register_class(VIEW3D_PT_rigify_animation_tools)
1329 bpy.utils.register_class(VIEW3D_PT_tools_rigify_dev)
1330 bpy.utils.register_class(LayerInit)
1331 bpy.utils.register_class(Generate)
1332 bpy.utils.register_class(UpgradeMetarigTypes)
1333 bpy.utils.register_class(SwitchToLegacy)
1334 bpy.utils.register_class(Sample)
1335 bpy.utils.register_class(EncodeMetarig)
1336 bpy.utils.register_class(EncodeMetarigSample)
1337 bpy.utils.register_class(EncodeWidget)
1338 bpy.utils.register_class(OBJECT_OT_GetFrameRange)
1339 bpy.utils.register_class(OBJECT_OT_FK2IK)
1340 bpy.utils.register_class(OBJECT_OT_IK2FK)
1341 bpy.utils.register_class(OBJECT_OT_TransferFKtoIK)
1342 bpy.utils.register_class(OBJECT_OT_TransferIKtoFK)
1343 bpy.utils.register_class(OBJECT_OT_ClearAnimation)
1344 bpy.utils.register_class(OBJECT_OT_Rot2Pole)
1346 rot_mode.register()
1349 def unregister():
1351 bpy.utils.unregister_class(DATA_OT_rigify_add_bone_groups)
1352 bpy.utils.unregister_class(DATA_OT_rigify_use_standard_colors)
1353 bpy.utils.unregister_class(DATA_OT_rigify_apply_selection_colors)
1354 bpy.utils.unregister_class(DATA_OT_rigify_bone_group_add)
1355 bpy.utils.unregister_class(DATA_OT_rigify_bone_group_add_theme)
1356 bpy.utils.unregister_class(DATA_OT_rigify_bone_group_remove)
1357 bpy.utils.unregister_class(DATA_OT_rigify_bone_group_remove_all)
1358 bpy.utils.unregister_class(DATA_UL_rigify_bone_groups)
1359 bpy.utils.unregister_class(DATA_MT_rigify_bone_groups_specials)
1360 bpy.utils.unregister_class(DATA_PT_rigify_bone_groups)
1361 bpy.utils.unregister_class(DATA_PT_rigify_layer_names)
1362 bpy.utils.unregister_class(DATA_PT_rigify_buttons)
1363 bpy.utils.unregister_class(BONE_PT_rigify_buttons)
1364 bpy.utils.unregister_class(VIEW3D_PT_rigify_animation_tools)
1365 bpy.utils.unregister_class(VIEW3D_PT_tools_rigify_dev)
1366 bpy.utils.unregister_class(LayerInit)
1367 bpy.utils.unregister_class(Generate)
1368 bpy.utils.unregister_class(UpgradeMetarigTypes)
1369 bpy.utils.unregister_class(SwitchToLegacy)
1370 bpy.utils.unregister_class(Sample)
1371 bpy.utils.unregister_class(EncodeMetarig)
1372 bpy.utils.unregister_class(EncodeMetarigSample)
1373 bpy.utils.unregister_class(EncodeWidget)
1374 bpy.utils.unregister_class(OBJECT_OT_GetFrameRange)
1375 bpy.utils.unregister_class(OBJECT_OT_FK2IK)
1376 bpy.utils.unregister_class(OBJECT_OT_IK2FK)
1377 bpy.utils.unregister_class(OBJECT_OT_TransferFKtoIK)
1378 bpy.utils.unregister_class(OBJECT_OT_TransferIKtoFK)
1379 bpy.utils.unregister_class(OBJECT_OT_ClearAnimation)
1380 bpy.utils.unregister_class(OBJECT_OT_Rot2Pole)
1382 rot_mode.unregister()