Skip to content
Snippets Groups Projects
Commit 71565f82 authored by Damien Picard's avatar Damien Picard Committed by Alexander Gavrilov
Browse files

Rigify: store advanced options in armature instead of window manager.

By storing the Rigify advanced generation options (name, target rig,
target ui script) in the armature data instead of the window manager
as before, multiple rigs can have different options. Additionally,
these options are stored in the blend file, and not lost when reloading.

Also, the rig name is not automatically suffixed with `_rig`, which
doesn't make sense as far as I can tell.

Differential Revision: https://developer.blender.org/D5675
parent 0260327c
Branches
Tags
No related merge requests found
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
bl_info = { bl_info = {
"name": "Rigify", "name": "Rigify",
"version": (0, 6, 0), "version": (0, 6, 1),
"author": "Nathan Vegdahl, Lucio Rossi, Ivan Cappiello, Alexander Gavrilov", "author": "Nathan Vegdahl, Lucio Rossi, Ivan Cappiello, Alexander Gavrilov",
"blender": (2, 81, 0), "blender": (2, 81, 0),
"description": "Automatic rigging from building-block components", "description": "Automatic rigging from building-block components",
...@@ -520,7 +520,7 @@ def register(): ...@@ -520,7 +520,7 @@ def register():
IDStore.rigify_types = CollectionProperty(type=RigifyName) IDStore.rigify_types = CollectionProperty(type=RigifyName)
IDStore.rigify_active_type = IntProperty(name="Rigify Active Type", description="The selected rig type") IDStore.rigify_active_type = IntProperty(name="Rigify Active Type", description="The selected rig type")
IDStore.rigify_advanced_generation = BoolProperty(name="Advanced Options", bpy.types.Armature.rigify_advanced_generation = BoolProperty(name="Advanced Options",
description="Enables/disables advanced options for Rigify rig generation", description="Enables/disables advanced options for Rigify rig generation",
default=False) default=False)
...@@ -528,27 +528,26 @@ def register(): ...@@ -528,27 +528,26 @@ def register():
if self.rigify_generate_mode == 'new': if self.rigify_generate_mode == 'new':
self.rigify_force_widget_update = False self.rigify_force_widget_update = False
IDStore.rigify_generate_mode = EnumProperty(name="Rigify Generate Rig Mode", bpy.types.Armature.rigify_generate_mode = EnumProperty(name="Rigify Generate Rig Mode",
description="'Generate Rig' mode. In 'overwrite' mode the features of the target rig will be updated as defined by the metarig. In 'new' mode a new rig will be created as defined by the metarig. Current mode", description="'Generate Rig' mode. In 'overwrite' mode the features of the target rig will be updated as defined by the metarig. In 'new' mode a new rig will be created as defined by the metarig. Current mode",
update=update_mode, update=update_mode,
items=( ('overwrite', 'overwrite', ''), items=( ('overwrite', 'overwrite', ''),
('new', 'new', ''))) ('new', 'new', '')))
IDStore.rigify_force_widget_update = BoolProperty(name="Force Widget Update", bpy.types.Armature.rigify_force_widget_update = BoolProperty(name="Force Widget Update",
description="Forces Rigify to delete and rebuild all the rig widgets. if unset, only missing widgets will be created", description="Forces Rigify to delete and rebuild all the rig widgets. if unset, only missing widgets will be created",
default=False) default=False)
IDStore.rigify_target_rigs = CollectionProperty(type=RigifyName) bpy.types.Armature.rigify_target_rig = PointerProperty(type=bpy.types.Object,
IDStore.rigify_target_rig = StringProperty(name="Rigify Target Rig", name="Rigify Target Rig",
description="Defines which rig to overwrite. If unset, a new one called 'rig' will be created", description="Defines which rig to overwrite. If unset, a new one called 'rig' will be created",
default="") poll=lambda self, obj: obj.type == 'ARMATURE' and obj.data is not self)
IDStore.rigify_rig_uis = CollectionProperty(type=RigifyName) bpy.types.Armature.rigify_rig_ui = PointerProperty(type=bpy.types.Text,
IDStore.rigify_rig_ui = StringProperty(name="Rigify Target Rig UI", name="Rigify Target Rig UI",
description="Defines the UI to overwrite. It should always be the same as the target rig. If unset, 'rig_ui.py' will be used", description="Defines the UI to overwrite. If unset, 'rig_ui.py' will be used")
default="")
IDStore.rigify_rig_basename = StringProperty(name="Rigify Rig Name", bpy.types.Armature.rigify_rig_basename = StringProperty(name="Rigify Rig Name",
description="Defines the name of the Rig. If unset, in 'new' mode 'rig' will be used, in 'overwrite' mode the target rig name will be used", description="Defines the name of the Rig. If unset, in 'new' mode 'rig' will be used, in 'overwrite' mode the target rig name will be used",
default="") default="")
...@@ -602,19 +601,17 @@ def unregister(): ...@@ -602,19 +601,17 @@ def unregister():
del ArmStore.rigify_colors_index del ArmStore.rigify_colors_index
del ArmStore.rigify_colors_lock del ArmStore.rigify_colors_lock
del ArmStore.rigify_theme_to_add del ArmStore.rigify_theme_to_add
del ArmStore.rigify_advanced_generation
del ArmStore.rigify_generate_mode
del ArmStore.rigify_force_widget_update
del ArmStore.rigify_target_rig
del ArmStore.rigify_rig_ui
del ArmStore.rigify_rig_basename
IDStore = bpy.types.WindowManager IDStore = bpy.types.WindowManager
del IDStore.rigify_collection del IDStore.rigify_collection
del IDStore.rigify_types del IDStore.rigify_types
del IDStore.rigify_active_type del IDStore.rigify_active_type
del IDStore.rigify_advanced_generation
del IDStore.rigify_generate_mode
del IDStore.rigify_force_widget_update
del IDStore.rigify_target_rig
del IDStore.rigify_target_rigs
del IDStore.rigify_rig_uis
del IDStore.rigify_rig_ui
del IDStore.rigify_rig_basename
del IDStore.rigify_transfer_only_selected del IDStore.rigify_transfer_only_selected
# Classes. # Classes.
......
...@@ -69,36 +69,45 @@ class Generator(base_generate.BaseGenerator): ...@@ -69,36 +69,45 @@ class Generator(base_generate.BaseGenerator):
def __create_rig_object(self): def __create_rig_object(self):
scene = self.scene scene = self.scene
id_store = self.id_store id_store = self.id_store
meta_data = self.metarig.data
# Check if the generated rig already exists, so we can # Check if the generated rig already exists, so we can
# regenerate in the same object. If not, create a new # regenerate in the same object. If not, create a new
# object to generate the rig in. # object to generate the rig in.
print("Fetch rig.") print("Fetch rig.")
if id_store.rigify_generate_mode == 'overwrite': self.rig_new_name = name = meta_data.rigify_rig_basename or "rig"
name = id_store.rigify_target_rig or "rig"
try: obj = None
if meta_data.rigify_generate_mode == 'overwrite':
obj = meta_data.rigify_target_rig
if not obj and name in scene.objects:
obj = scene.objects[name] obj = scene.objects[name]
self.rig_old_name = name
obj.name = self.rig_new_name or name if obj:
self.rig_old_name = obj.name
obj.name = name
obj.data.name = obj.name
rig_collections = filter_layer_collections_by_object(self.usable_collections, obj) rig_collections = filter_layer_collections_by_object(self.usable_collections, obj)
self.layer_collection = (rig_collections + [self.layer_collection])[0] self.layer_collection = (rig_collections + [self.layer_collection])[0]
self.collection = self.layer_collection.collection self.collection = self.layer_collection.collection
except KeyError: elif name in bpy.data.objects:
self.rig_old_name = name obj = bpy.data.objects[name]
name = self.rig_new_name or name
if not obj:
obj = bpy.data.objects.new(name, bpy.data.armatures.new(name)) obj = bpy.data.objects.new(name, bpy.data.armatures.new(name))
obj.display_type = 'WIRE' obj.display_type = 'WIRE'
self.collection.objects.link(obj) self.collection.objects.link(obj)
else:
name = self.rig_new_name or "rig" elif obj.name not in self.collection.objects: # rig exists but was deleted
obj = bpy.data.objects.new(name, bpy.data.armatures.new(name)) # in case name 'rig' exists it will be rig.001
obj.display_type = 'WIRE'
self.collection.objects.link(obj) self.collection.objects.link(obj)
id_store.rigify_target_rig = obj.name meta_data.rigify_target_rig = obj
obj.data.pose_position = 'POSE' obj.data.pose_position = 'POSE'
self.obj = obj self.obj = obj
...@@ -114,8 +123,8 @@ class Generator(base_generate.BaseGenerator): ...@@ -114,8 +123,8 @@ class Generator(base_generate.BaseGenerator):
self.widget_collection = ensure_widget_collection(context) self.widget_collection = ensure_widget_collection(context)
# Remove wgts if force update is set # Remove wgts if force update is set
wgts_group_name = "WGTS_" + (self.rig_old_name or obj.name) wgts_group_name = "WGTS_" + (self.rig_old_name or self.obj.name)
if wgts_group_name in scene.objects and id_store.rigify_force_widget_update: if wgts_group_name in scene.objects and self.metarig.data.rigify_force_widget_update:
bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.select_all(action='DESELECT') bpy.ops.object.select_all(action='DESELECT')
for wgt in bpy.data.objects[wgts_group_name].children: for wgt in bpy.data.objects[wgts_group_name].children:
...@@ -320,9 +329,6 @@ class Generator(base_generate.BaseGenerator): ...@@ -320,9 +329,6 @@ class Generator(base_generate.BaseGenerator):
#------------------------------------------ #------------------------------------------
# Create/find the rig object and set it up # Create/find the rig object and set it up
if id_store.rigify_rig_basename:
self.rig_new_name = id_store.rigify_rig_basename + "_rig"
obj = self.__create_rig_object() obj = self.__create_rig_object()
# Get rid of anim data in case the rig already existed # Get rid of anim data in case the rig already existed
......
...@@ -1147,7 +1147,6 @@ class ScriptGenerator(base_generate.GeneratorPlugin): ...@@ -1147,7 +1147,6 @@ class ScriptGenerator(base_generate.GeneratorPlugin):
def finalize(self): def finalize(self):
metarig = self.generator.metarig metarig = self.generator.metarig
id_store = self.generator.id_store
rig_id = self.generator.rig_id rig_id = self.generator.rig_id
vis_layers = self.obj.data.layers vis_layers = self.obj.data.layers
...@@ -1162,23 +1161,27 @@ class ScriptGenerator(base_generate.GeneratorPlugin): ...@@ -1162,23 +1161,27 @@ class ScriptGenerator(base_generate.GeneratorPlugin):
layer_layout += [(l.name, l.row)] layer_layout += [(l.name, l.row)]
# Generate the UI script # Generate the UI script
if id_store.rigify_generate_mode == 'overwrite': if metarig.data.rigify_rig_basename:
rig_ui_name = id_store.rigify_rig_ui or 'rig_ui.py' rig_ui_name = metarig.data.rigify_rig_basename + '_rig_ui.py'
else: else:
rig_ui_name = 'rig_ui.py' rig_ui_name = 'rig_ui.py'
if id_store.rigify_generate_mode == 'overwrite' and rig_ui_name in bpy.data.texts.keys(): script = None
if metarig.data.rigify_generate_mode == 'overwrite':
script = metarig.data.rigify_rig_ui
if not script and rig_ui_name in bpy.data.texts:
script = bpy.data.texts[rig_ui_name] script = bpy.data.texts[rig_ui_name]
if script:
script.clear() script.clear()
else: script.name = rig_ui_name
script = bpy.data.texts.new("rig_ui.py")
rig_ui_old_name = "" if script is None:
if id_store.rigify_rig_basename: script = bpy.data.texts.new(rig_ui_name)
rig_ui_old_name = script.name
script.name = id_store.rigify_rig_basename + "_rig_ui.py"
id_store.rigify_rig_ui = script.name metarig.data.rigify_rig_ui = script
for s in OrderedDict.fromkeys(self.ui_imports): for s in OrderedDict.fromkeys(self.ui_imports):
script.write(s + "\n") script.write(s + "\n")
......
...@@ -77,6 +77,7 @@ class DATA_PT_rigify_buttons(bpy.types.Panel): ...@@ -77,6 +77,7 @@ class DATA_PT_rigify_buttons(bpy.types.Panel):
id_store = C.window_manager id_store = C.window_manager
if obj.mode in {'POSE', 'OBJECT'}: if obj.mode in {'POSE', 'OBJECT'}:
armature_id_store = C.object.data
WARNING = "Warning: Some features may change after generation" WARNING = "Warning: Some features may change after generation"
show_warning = False show_warning = False
...@@ -127,7 +128,7 @@ class DATA_PT_rigify_buttons(bpy.types.Panel): ...@@ -127,7 +128,7 @@ class DATA_PT_rigify_buttons(bpy.types.Panel):
row.enabled = enable_generate_and_advanced row.enabled = enable_generate_and_advanced
if id_store.rigify_advanced_generation: if armature_id_store.rigify_advanced_generation:
icon = 'UNLOCKED' icon = 'UNLOCKED'
else: else:
icon = 'LOCKED' icon = 'LOCKED'
...@@ -135,12 +136,12 @@ class DATA_PT_rigify_buttons(bpy.types.Panel): ...@@ -135,12 +136,12 @@ class DATA_PT_rigify_buttons(bpy.types.Panel):
col = layout.column() col = layout.column()
col.enabled = enable_generate_and_advanced col.enabled = enable_generate_and_advanced
row = col.row() row = col.row()
row.prop(id_store, "rigify_advanced_generation", toggle=True, icon=icon) row.prop(armature_id_store, "rigify_advanced_generation", toggle=True, icon=icon)
if id_store.rigify_advanced_generation: if armature_id_store.rigify_advanced_generation:
row = col.row(align=True) row = col.row(align=True)
row.prop(id_store, "rigify_generate_mode", expand=True) row.prop(armature_id_store, "rigify_generate_mode", expand=True)
main_row = col.row(align=True).split(factor=0.3) main_row = col.row(align=True).split(factor=0.3)
col1 = main_row.column() col1 = main_row.column()
...@@ -148,41 +149,25 @@ class DATA_PT_rigify_buttons(bpy.types.Panel): ...@@ -148,41 +149,25 @@ class DATA_PT_rigify_buttons(bpy.types.Panel):
col1.label(text="Rig Name") col1.label(text="Rig Name")
row = col1.row() row = col1.row()
row.label(text="Target Rig") row.label(text="Target Rig")
row.enabled = (id_store.rigify_generate_mode == "overwrite") row.enabled = (armature_id_store.rigify_generate_mode == "overwrite")
row = col1.row() row = col1.row()
row.label(text="Target UI") row.label(text="Target UI")
row.enabled = (id_store.rigify_generate_mode == "overwrite") row.enabled = (armature_id_store.rigify_generate_mode == "overwrite")
row = col2.row(align=True) row = col2.row(align=True)
row.prop(id_store, "rigify_rig_basename", text="", icon="SORTALPHA") row.prop(armature_id_store, "rigify_rig_basename", text="", icon="SORTALPHA")
row = col2.row(align=True) row = col2.row(align=True)
for i in range(0, len(id_store.rigify_target_rigs)): row.prop(armature_id_store, "rigify_target_rig", text="")
id_store.rigify_target_rigs.remove(0) row.enabled = (armature_id_store.rigify_generate_mode == "overwrite")
for ob in context.scene.objects:
if type(ob.data) == bpy.types.Armature and "rig_id" in ob.data:
id_store.rigify_target_rigs.add()
id_store.rigify_target_rigs[-1].name = ob.name
row.prop_search(id_store, "rigify_target_rig", id_store, "rigify_target_rigs", text="",
icon='OUTLINER_OB_ARMATURE')
row.enabled = (id_store.rigify_generate_mode == "overwrite")
for i in range(0, len(id_store.rigify_rig_uis)):
id_store.rigify_rig_uis.remove(0)
for t in bpy.data.texts:
id_store.rigify_rig_uis.add()
id_store.rigify_rig_uis[-1].name = t.name
row = col2.row() row = col2.row()
row.prop_search(id_store, "rigify_rig_ui", id_store, "rigify_rig_uis", text="", icon='TEXT') row.prop(armature_id_store, "rigify_rig_ui", text="", icon='TEXT')
row.enabled = (id_store.rigify_generate_mode == "overwrite") row.enabled = (armature_id_store.rigify_generate_mode == "overwrite")
row = col.row() row = col.row()
row.prop(id_store, "rigify_force_widget_update") row.prop(armature_id_store, "rigify_force_widget_update")
if id_store.rigify_generate_mode == 'new': if armature_id_store.rigify_generate_mode == 'new':
row.enabled = False row.enabled = False
elif obj.mode == 'EDIT': elif obj.mode == 'EDIT':
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment