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:
authorAlexander Gavrilov <angavrilov@gmail.com>2019-02-16 13:57:57 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2019-03-14 14:39:16 +0300
commit36e8d00aec705b06008a0bc334fe266448b4f2c2 (patch)
tree02bf0290ec6423c611e3cd4ad49c69cb77acb67e /rigify/generate.py
parenteabb5cddf79e5fae3ca429242cf2c6f5a272920e (diff)
Rigify: add support for user-defined rig packages and related utilities.
As suggested by @icappielo, and after discussion with @meta-androcto, I start a public request to commit third-party contributions already accepted to https://github.com/eigen-value/rigify/tree/rigify_0.6_beta Specifically, this includes: * User-defined rig package (feature set) support by @pioverfour. This allows users to install pre-packaged rig sets via zip files, which become accessible together with built-in rigs, as discussed in T52758. https://github.com/eigen-value/rigify/pull/1 * Modularization of python script generation, allowing rigs to add their own utility functions and operators to the generated script. This is critical to make custom rig support really useful. https://github.com/eigen-value/rigify/pull/5 * The utils.py file is split into multiple modules with a backward compatibility proxy for old functions. * Automatic verification that different rigs don't try to create different rig settings with the same name to alleviate increased risk of namespace conflicts with custom rigs. https://github.com/eigen-value/rigify/pull/7 * New utility class that implements bone layer selection UI. https://github.com/eigen-value/rigify/pull/6 * New utilities to replace copy & pasted boilerplate code for creating custom properties, constraints and drivers. https://github.com/eigen-value/rigify/pull/11 Some other random changes by MAD have likely slipped through. These changes have already been extensively discussed and accepted into the branch by @luciorossi, so I see no reason not to commit them to the official repository to be tested during 2.8 beta. Reviewers: icappiello Differential Revision: https://developer.blender.org/D4364
Diffstat (limited to 'rigify/generate.py')
-rw-r--r--rigify/generate.py87
1 files changed, 56 insertions, 31 deletions
diff --git a/rigify/generate.py b/rigify/generate.py
index 5b5f0e98..7eff06f3 100644
--- a/rigify/generate.py
+++ b/rigify/generate.py
@@ -24,17 +24,17 @@ import time
import traceback
import sys
from rna_prop_ui import rna_idprop_ui_prop_get
+from collections import OrderedDict
-from .utils import MetarigError, new_bone, get_rig_type
-from .utils import ORG_PREFIX, MCH_PREFIX, DEF_PREFIX, WGT_PREFIX, ROOT_NAME, make_original_name
-from .utils import RIG_DIR
+from .utils import MetarigError, new_bone
+from .utils import MCH_PREFIX, DEF_PREFIX, WGT_PREFIX, ROOT_NAME, make_original_name
from .utils import create_root_widget
-from .utils import ensure_widget_collection
+from .utils.collections import ensure_widget_collection
from .utils import random_id
from .utils import copy_attributes
from .utils import gamma_correct
-from .rig_ui_template import UI_SLIDERS, layers_ui, UI_REGISTER
-
+from . import rig_lists
+from . import rig_ui_template
RIG_MODULE = "rigs"
ORG_LAYER = [n == 31 for n in range(0, 32)] # Armature layer that original bones should be moved to.
@@ -123,6 +123,7 @@ def generate_rig(context, metarig):
# Remove wgts if force update is set
wgts_group_name = "WGTS_" + (rig_old_name or obj.name)
if wgts_group_name in scene.objects and id_store.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:
wgt.select_set(True)
@@ -301,6 +302,8 @@ def generate_rig(context, metarig):
rna_idprop_ui_prop_get(obj.data, "rig_id", create=True)
obj.data["rig_id"] = rig_id
+ t.tick("Create root bone: ")
+
# Create/find widge collection
widget_collection = ensure_widget_collection(context)
@@ -332,6 +335,10 @@ def generate_rig(context, metarig):
# Generate all the rigs.
ui_scripts = []
+ ui_imports = rig_ui_template.UI_IMPORTS.copy()
+ ui_utilities = rig_ui_template.UI_UTILITIES.copy()
+ ui_register = rig_ui_template.UI_REGISTER.copy()
+ noparent_bones = []
for rig in rigs:
# Go into editmode in the rig armature
bpy.ops.object.mode_set(mode='OBJECT')
@@ -339,9 +346,21 @@ def generate_rig(context, metarig):
obj.select_set(True)
bpy.ops.object.mode_set(mode='EDIT')
scripts = rig.generate()
- if scripts is not None:
+ if isinstance(scripts, dict):
+ if 'script' in scripts:
+ ui_scripts += scripts['script']
+ if 'imports' in scripts:
+ ui_imports += scripts['imports']
+ if 'utilities' in scripts:
+ ui_utilities += scripts['utilities']
+ if 'register' in scripts:
+ ui_register += scripts['register']
+ if 'noparent_bones' in scripts:
+ noparent_bones += scripts['noparent_bones']
+ elif scripts is not None:
ui_scripts += [scripts[0]]
t.tick("Generate rigs: ")
+
except Exception as e:
# Cleanup if something goes wrong
print("Rigify: failed to generate rig.")
@@ -358,25 +377,8 @@ def generate_rig(context, metarig):
# Get a list of all the bones in the armature
bones = [bone.name for bone in obj.data.bones]
- # Parent any free-floating bones to the root excluding bones with child of constraint.
- pbones = obj.pose.bones
-
-
- ik_follow_drivers = []
-
- if obj.animation_data:
- for drv in obj.animation_data.drivers:
- for var in drv.driver.variables:
- if 'IK_follow' == var.name:
- ik_follow_drivers.append(drv.data_path)
-
- noparent_bones = []
- for bone in bones:
- # if 'IK_follow' in pbones[bone].keys():
- # noparent_bones += [bone]
- for d in ik_follow_drivers:
- if bone in d:
- noparent_bones += [bone]
+ # Parent any free-floating bones to the root excluding noparent_bones
+ noparent_bones = dict.fromkeys(noparent_bones)
bpy.ops.object.mode_set(mode='EDIT')
for bone in bones:
@@ -486,11 +488,23 @@ def generate_rig(context, metarig):
id_store.rigify_rig_ui = script.name
- script.write(UI_SLIDERS % rig_id)
+ for s in OrderedDict.fromkeys(ui_imports):
+ script.write(s + "\n")
+ script.write(rig_ui_template.UI_BASE_UTILITIES % rig_id)
+ for s in OrderedDict.fromkeys(ui_utilities):
+ script.write(s + "\n")
+ script.write(rig_ui_template.UI_SLIDERS)
for s in ui_scripts:
script.write("\n " + s.replace("\n", "\n ") + "\n")
- script.write(layers_ui(vis_layers, layer_layout))
- script.write(UI_REGISTER)
+ script.write(rig_ui_template.layers_ui(vis_layers, layer_layout))
+ script.write("\ndef register():\n")
+ ui_register = OrderedDict.fromkeys(ui_register)
+ for s in ui_register:
+ script.write(" bpy.utils.register_class("+s+");\n")
+ script.write("\ndef unregister():\n")
+ for s in ui_register:
+ script.write(" bpy.utils.unregister_class("+s+");\n")
+ script.write("\nregister()\n")
script.use_module = True
# Run UI script
@@ -505,6 +519,16 @@ def generate_rig(context, metarig):
# Add rig_ui to logic
create_persistent_rig_ui(obj, script)
+ # Do final gluing
+ for rig in rigs:
+ if hasattr(rig, "glue"):
+ # update glue_bone rigs
+ bpy.ops.object.mode_set(mode='EDIT')
+ rig = rig.__class__(rig.obj, rig.base_bone, rig.params)
+
+ rig.glue()
+ t.tick("Glue pass")
+
t.tick("The rest: ")
#----------------------------------
# Deconfigure
@@ -636,8 +660,9 @@ def get_bone_rigs(obj, bone_name, halt_on_missing=False):
# Get the rig
try:
- rig = get_rig_type(rig_type).Rig(obj, bone_name, params)
- except ImportError:
+ rig = rig_lists.rigs[rig_type]["module"]
+ rig = rig.Rig(obj, bone_name, params)
+ except (KeyError, ImportError):
message = "Rig Type Missing: python module for type '%s' not found (bone: %s)" % (rig_type, bone_name)
if halt_on_missing:
raise MetarigError(message)