diff options
author | Alexander Gavrilov <angavrilov@gmail.com> | 2019-02-16 13:57:57 +0300 |
---|---|---|
committer | Alexander Gavrilov <angavrilov@gmail.com> | 2019-03-14 14:39:16 +0300 |
commit | 36e8d00aec705b06008a0bc334fe266448b4f2c2 (patch) | |
tree | 02bf0290ec6423c611e3cd4ad49c69cb77acb67e /rigify/rig_lists.py | |
parent | eabb5cddf79e5fae3ca429242cf2c6f5a272920e (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/rig_lists.py')
-rw-r--r-- | rigify/rig_lists.py | 89 |
1 files changed, 45 insertions, 44 deletions
diff --git a/rigify/rig_lists.py b/rigify/rig_lists.py index edca1090..c1846b99 100644 --- a/rigify/rig_lists.py +++ b/rigify/rig_lists.py @@ -21,69 +21,70 @@ import os from . import utils -def get_rig_list(path): +def get_rigs(base_path, path, feature_set='rigify'): """ Recursively searches for rig types, and returns a list. + + :param base_path: base dir where rigs are stored + :type path:str + :param path: rig path inside the base dir + :type path:str """ - rigs_dict = dict() - rigs = [] - implementation_rigs = [] - MODULE_DIR = os.path.dirname(__file__) - RIG_DIR_ABS = os.path.join(MODULE_DIR, utils.RIG_DIR) - SEARCH_DIR_ABS = os.path.join(RIG_DIR_ABS, path) - files = os.listdir(SEARCH_DIR_ABS) + + rigs = {} + impl_rigs = {} + + files = os.listdir(os.path.join(base_path, path)) files.sort() for f in files: - is_dir = os.path.isdir(os.path.join(SEARCH_DIR_ABS, f)) # Whether the file is a directory + is_dir = os.path.isdir(os.path.join(base_path, path, f)) # Whether the file is a directory # Stop cases if f[0] in [".", "_"]: continue if f.count(".") >= 2 or (is_dir and "." in f): - print("Warning: %r, filename contains a '.', skipping" % os.path.join(SEARCH_DIR_ABS, f)) + print("Warning: %r, filename contains a '.', skipping" % os.path.join(path, f)) continue if is_dir: # Check directories - module_name = os.path.join(path, f).replace(os.sep, ".") - rig = utils.get_rig_type(module_name) - # Check if it's a rig itself - if hasattr(rig, "Rig"): - rigs += [f] - else: - # Check for sub-rigs - sub_dict = get_rig_list(os.path.join(path, f, "")) # "" adds a final slash - rigs.extend(["%s.%s" % (f, l) for l in sub_dict['rig_list']]) - implementation_rigs.extend(["%s.%s" % (f, l) for l in sub_dict['implementation_rigs']]) + module_name = os.path.join(path, "__init__").replace(os.sep, ".") + # Check for sub-rigs + sub_rigs, sub_impls = get_rigs(base_path, os.path.join(path, f, ""), feature_set) # "" adds a final slash + rigs.update({"%s.%s" % (f, l): sub_rigs[l] for l in sub_rigs}) + impl_rigs.update({"%s.%s" % (f, l): sub_rigs[l] for l in sub_impls}) elif f.endswith(".py"): # Check straight-up python files - t = f[:-3] - module_name = os.path.join(path, t).replace(os.sep, ".") - rig = utils.get_rig_type(module_name) - if hasattr(rig, "Rig"): - rigs += [t] - if hasattr(rig, 'IMPLEMENTATION') and rig.IMPLEMENTATION: - implementation_rigs += [t] - rigs.sort() + f = f[:-3] + module_name = os.path.join(path, f).replace(os.sep, ".") + rig_module = utils.get_resource(module_name, base_path=base_path) + if hasattr(rig_module, "Rig"): + rigs[f] = {"module": rig_module, + "feature_set": feature_set} + if hasattr(rig_module, 'IMPLEMENTATION') and rig_module.IMPLEMENTATION: + impl_rigs[f] = rig_module + + return rigs, impl_rigs - rigs_dict['rig_list'] = rigs - rigs_dict['implementation_rigs'] = implementation_rigs - return rigs_dict +# Public variables +MODULE_DIR = os.path.dirname(os.path.dirname(__file__)) +rigs, implementation_rigs = get_rigs(MODULE_DIR, os.path.join(os.path.basename(os.path.dirname(__file__)), utils.RIG_DIR, '')) -def get_collection_list(rig_list): - collection_list = [] - for r in rig_list: - a = r.split(".") - if len(a) >= 2 and a[0] not in collection_list: - collection_list += [a[0]] - return collection_list +def get_external_rigs(feature_sets_path): + # Clear and fill rigify rigs and implementation rigs public variables + for rig in list(rigs.keys()): + if rigs[rig]["feature_set"] != "rigify": + rigs.pop(rig) + if rig in implementation_rigs: + implementation_rigs.pop(rig) -# Public variables -rigs_dict = get_rig_list("") -rig_list = rigs_dict['rig_list'] -implementation_rigs = rigs_dict['implementation_rigs'] -collection_list = get_collection_list(rig_list) -col_enum_list = [("All", "All", ""), ("None", "None", "")] + [(c, c, "") for c in collection_list] + # Get external rigs + for feature_set in os.listdir(feature_sets_path): + if feature_set: + utils.get_resource(os.path.join(feature_set, '__init__'), feature_sets_path) + external_rigs, external_impl_rigs = get_rigs(feature_sets_path, os.path.join(feature_set, utils.RIG_DIR), feature_set) + rigs.update(external_rigs) + implementation_rigs.update(external_impl_rigs) |