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
This commit is contained in:
parent
0260327cff
commit
71565f82b2
Notes:
blender-bot
2023-02-14 18:07:07 +01:00
Referenced by commit ed5b81f5: Fix T71678: Rigify crash if the Advanced mode is set to New.
Referenced by commit ed5b81f5
, Fix T71678: Rigify crash if the Advanced mode is set to New.
|
@ -20,7 +20,7 @@
|
|||
|
||||
bl_info = {
|
||||
"name": "Rigify",
|
||||
"version": (0, 6, 0),
|
||||
"version": (0, 6, 1),
|
||||
"author": "Nathan Vegdahl, Lucio Rossi, Ivan Cappiello, Alexander Gavrilov",
|
||||
"blender": (2, 81, 0),
|
||||
"description": "Automatic rigging from building-block components",
|
||||
|
@ -520,7 +520,7 @@ def register():
|
|||
IDStore.rigify_types = CollectionProperty(type=RigifyName)
|
||||
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",
|
||||
default=False)
|
||||
|
||||
|
@ -528,27 +528,26 @@ def register():
|
|||
if self.rigify_generate_mode == 'new':
|
||||
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",
|
||||
update=update_mode,
|
||||
items=( ('overwrite', 'overwrite', ''),
|
||||
('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",
|
||||
default=False)
|
||||
|
||||
IDStore.rigify_target_rigs = CollectionProperty(type=RigifyName)
|
||||
IDStore.rigify_target_rig = StringProperty(name="Rigify Target Rig",
|
||||
bpy.types.Armature.rigify_target_rig = PointerProperty(type=bpy.types.Object,
|
||||
name="Rigify Target Rig",
|
||||
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)
|
||||
IDStore.rigify_rig_ui = StringProperty(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",
|
||||
default="")
|
||||
bpy.types.Armature.rigify_rig_ui = PointerProperty(type=bpy.types.Text,
|
||||
name="Rigify Target Rig UI",
|
||||
description="Defines the UI to overwrite. If unset, 'rig_ui.py' will be used")
|
||||
|
||||
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",
|
||||
default="")
|
||||
|
||||
|
@ -602,19 +601,17 @@ def unregister():
|
|||
del ArmStore.rigify_colors_index
|
||||
del ArmStore.rigify_colors_lock
|
||||
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
|
||||
del IDStore.rigify_collection
|
||||
del IDStore.rigify_types
|
||||
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
|
||||
|
||||
# Classes.
|
||||
|
|
|
@ -69,36 +69,45 @@ class Generator(base_generate.BaseGenerator):
|
|||
def __create_rig_object(self):
|
||||
scene = self.scene
|
||||
id_store = self.id_store
|
||||
meta_data = self.metarig.data
|
||||
|
||||
# Check if the generated rig already exists, so we can
|
||||
# regenerate in the same object. If not, create a new
|
||||
# object to generate the rig in.
|
||||
print("Fetch rig.")
|
||||
|
||||
if id_store.rigify_generate_mode == 'overwrite':
|
||||
name = id_store.rigify_target_rig or "rig"
|
||||
try:
|
||||
self.rig_new_name = name = meta_data.rigify_rig_basename or "rig"
|
||||
|
||||
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]
|
||||
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)
|
||||
self.layer_collection = (rig_collections + [self.layer_collection])[0]
|
||||
self.collection = self.layer_collection.collection
|
||||
|
||||
except KeyError:
|
||||
self.rig_old_name = name
|
||||
name = self.rig_new_name or name
|
||||
obj = bpy.data.objects.new(name, bpy.data.armatures.new(name))
|
||||
obj.display_type = 'WIRE'
|
||||
self.collection.objects.link(obj)
|
||||
else:
|
||||
name = self.rig_new_name or "rig"
|
||||
obj = bpy.data.objects.new(name, bpy.data.armatures.new(name)) # in case name 'rig' exists it will be rig.001
|
||||
elif name in bpy.data.objects:
|
||||
obj = bpy.data.objects[name]
|
||||
|
||||
if not obj:
|
||||
obj = bpy.data.objects.new(name, bpy.data.armatures.new(name))
|
||||
obj.display_type = 'WIRE'
|
||||
self.collection.objects.link(obj)
|
||||
|
||||
id_store.rigify_target_rig = obj.name
|
||||
elif obj.name not in self.collection.objects: # rig exists but was deleted
|
||||
self.collection.objects.link(obj)
|
||||
|
||||
meta_data.rigify_target_rig = obj
|
||||
obj.data.pose_position = 'POSE'
|
||||
|
||||
self.obj = obj
|
||||
|
@ -114,8 +123,8 @@ class Generator(base_generate.BaseGenerator):
|
|||
self.widget_collection = ensure_widget_collection(context)
|
||||
|
||||
# Remove wgts if force update is set
|
||||
wgts_group_name = "WGTS_" + (self.rig_old_name or obj.name)
|
||||
if wgts_group_name in scene.objects and id_store.rigify_force_widget_update:
|
||||
wgts_group_name = "WGTS_" + (self.rig_old_name or self.obj.name)
|
||||
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.select_all(action='DESELECT')
|
||||
for wgt in bpy.data.objects[wgts_group_name].children:
|
||||
|
@ -320,9 +329,6 @@ class Generator(base_generate.BaseGenerator):
|
|||
|
||||
#------------------------------------------
|
||||
# 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()
|
||||
|
||||
# Get rid of anim data in case the rig already existed
|
||||
|
|
|
@ -1147,7 +1147,6 @@ class ScriptGenerator(base_generate.GeneratorPlugin):
|
|||
|
||||
def finalize(self):
|
||||
metarig = self.generator.metarig
|
||||
id_store = self.generator.id_store
|
||||
rig_id = self.generator.rig_id
|
||||
|
||||
vis_layers = self.obj.data.layers
|
||||
|
@ -1162,23 +1161,27 @@ class ScriptGenerator(base_generate.GeneratorPlugin):
|
|||
layer_layout += [(l.name, l.row)]
|
||||
|
||||
# Generate the UI script
|
||||
if id_store.rigify_generate_mode == 'overwrite':
|
||||
rig_ui_name = id_store.rigify_rig_ui or 'rig_ui.py'
|
||||
if metarig.data.rigify_rig_basename:
|
||||
rig_ui_name = metarig.data.rigify_rig_basename + '_rig_ui.py'
|
||||
else:
|
||||
rig_ui_name = 'rig_ui.py'
|
||||
|
||||
if id_store.rigify_generate_mode == 'overwrite' and rig_ui_name in bpy.data.texts.keys():
|
||||
script = bpy.data.texts[rig_ui_name]
|
||||
script.clear()
|
||||
else:
|
||||
script = bpy.data.texts.new("rig_ui.py")
|
||||
script = None
|
||||
|
||||
rig_ui_old_name = ""
|
||||
if id_store.rigify_rig_basename:
|
||||
rig_ui_old_name = script.name
|
||||
script.name = id_store.rigify_rig_basename + "_rig_ui.py"
|
||||
if metarig.data.rigify_generate_mode == 'overwrite':
|
||||
script = metarig.data.rigify_rig_ui
|
||||
|
||||
id_store.rigify_rig_ui = script.name
|
||||
if not script and rig_ui_name in bpy.data.texts:
|
||||
script = bpy.data.texts[rig_ui_name]
|
||||
|
||||
if script:
|
||||
script.clear()
|
||||
script.name = rig_ui_name
|
||||
|
||||
if script is None:
|
||||
script = bpy.data.texts.new(rig_ui_name)
|
||||
|
||||
metarig.data.rigify_rig_ui = script
|
||||
|
||||
for s in OrderedDict.fromkeys(self.ui_imports):
|
||||
script.write(s + "\n")
|
||||
|
|
43
rigify/ui.py
43
rigify/ui.py
|
@ -77,6 +77,7 @@ class DATA_PT_rigify_buttons(bpy.types.Panel):
|
|||
id_store = C.window_manager
|
||||
|
||||
if obj.mode in {'POSE', 'OBJECT'}:
|
||||
armature_id_store = C.object.data
|
||||
|
||||
WARNING = "Warning: Some features may change after generation"
|
||||
show_warning = False
|
||||
|
@ -127,7 +128,7 @@ class DATA_PT_rigify_buttons(bpy.types.Panel):
|
|||
|
||||
row.enabled = enable_generate_and_advanced
|
||||
|
||||
if id_store.rigify_advanced_generation:
|
||||
if armature_id_store.rigify_advanced_generation:
|
||||
icon = 'UNLOCKED'
|
||||
else:
|
||||
icon = 'LOCKED'
|
||||
|
@ -135,12 +136,12 @@ class DATA_PT_rigify_buttons(bpy.types.Panel):
|
|||
col = layout.column()
|
||||
col.enabled = enable_generate_and_advanced
|
||||
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.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)
|
||||
col1 = main_row.column()
|
||||
|
@ -148,41 +149,25 @@ class DATA_PT_rigify_buttons(bpy.types.Panel):
|
|||
col1.label(text="Rig Name")
|
||||
row = col1.row()
|
||||
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.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.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)
|
||||
for i in range(0, len(id_store.rigify_target_rigs)):
|
||||
id_store.rigify_target_rigs.remove(0)
|
||||
|
||||
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.prop(armature_id_store, "rigify_target_rig", text="")
|
||||
row.enabled = (armature_id_store.rigify_generate_mode == "overwrite")
|
||||
|
||||
row = col2.row()
|
||||
row.prop_search(id_store, "rigify_rig_ui", id_store, "rigify_rig_uis", text="", icon='TEXT')
|
||||
row.enabled = (id_store.rigify_generate_mode == "overwrite")
|
||||
row.prop(armature_id_store, "rigify_rig_ui", text="", icon='TEXT')
|
||||
row.enabled = (armature_id_store.rigify_generate_mode == "overwrite")
|
||||
|
||||
row = col.row()
|
||||
row.prop(id_store, "rigify_force_widget_update")
|
||||
if id_store.rigify_generate_mode == 'new':
|
||||
row.prop(armature_id_store, "rigify_force_widget_update")
|
||||
if armature_id_store.rigify_generate_mode == 'new':
|
||||
row.enabled = False
|
||||
|
||||
elif obj.mode == 'EDIT':
|
||||
|
|
Loading…
Reference in New Issue