From 71565f82b24c27dbb45eadd8ca6c494996267039 Mon Sep 17 00:00:00 2001 From: Damien Picard <pioverfour> Date: Tue, 15 Oct 2019 13:31:12 +0300 Subject: [PATCH] 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 --- rigify/__init__.py | 37 +++++++++++++++---------------- rigify/generate.py | 46 ++++++++++++++++++++++----------------- rigify/rig_ui_template.py | 29 +++++++++++++----------- rigify/ui.py | 43 ++++++++++++------------------------ 4 files changed, 73 insertions(+), 82 deletions(-) diff --git a/rigify/__init__.py b/rigify/__init__.py index 803c19c0b..8363d037c 100644 --- a/rigify/__init__.py +++ b/rigify/__init__.py @@ -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. diff --git a/rigify/generate.py b/rigify/generate.py index 88b216ed6..295c1a503 100644 --- a/rigify/generate.py +++ b/rigify/generate.py @@ -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 diff --git a/rigify/rig_ui_template.py b/rigify/rig_ui_template.py index d7c2e8704..888f68711 100644 --- a/rigify/rig_ui_template.py +++ b/rigify/rig_ui_template.py @@ -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 + + 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] + + if script: + script.clear() + script.name = rig_ui_name - 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 script is None: + script = bpy.data.texts.new(rig_ui_name) - id_store.rigify_rig_ui = script.name + metarig.data.rigify_rig_ui = script for s in OrderedDict.fromkeys(self.ui_imports): script.write(s + "\n") diff --git a/rigify/ui.py b/rigify/ui.py index dacbd0a24..7f59e4b42 100644 --- a/rigify/ui.py +++ b/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': -- GitLab