Skip to content

Feature Set Package Structure

Feature sets are packaged as a ZIP archive containing a valid Python module package, with specific required sub-packages:

feature_set_name
  __init__.py
  metarigs
    __init__.py
   feature_set
     __init__.py
     feature_set_metarig.py
  rigs
    __init__.py
   feature_set
     __init__.py
     custom_rig.py

When an archive containing these files is installed, it will add a Feature Set -\> Feature Set Metarig template to the Add Armature menu, and, provided custom_rig.py contains a valid rig class, a feature_set.custom_rig rig component will become available. The metarigs subpackage is optional, while rigs is required.

The rigs and metarigs packages of all feature sets and Rigify itself are merged into a common flat namespace, so feature sets should explicitly use sub-packages to group and separate the provided rigs, as demonstrated above.

The root directory of the archive must be a valid python module name (i.e. an identifier); however as a special exceptions the characters '.' and '-' will be automatically replaced with '_' when the archive is installed. The exception is provided to allow using archives produced by the Download ZIP button on GitHub as-is.

The root __init__.py of the feature set may contain the following global variable definition to provide a user-friendly name and other metadata for the feature set:

rigify_info = {
    "name": "Custom Feature Set",
    "description": "More detailed description.\nSecond line of description.",
    "author": "Author Name",
    "warning": "Warning message, e.g. the set is experimental.",
    # Web site links
    "link": "https://github.com/repository/link",
    "doc_url": "https://documentation/link",
    "tracker_url": "https://bug/tracker/link",
    # Feature set version
    "version": (1, 2, 3),
    # Minimum supported Blender version
    "blender": (4, 0, 0),
    # List of other feature sets this one depends on, if any
    # (must be an exact copy of their "link" values)
    "dependencies": ["https://github.com/other-repository/link"],
}

It can also provide register and unregister functions, like stand-alone add-ons, in order to implement more complex utilities for editing the meta-rig than passive properties in the rig settings UI. The generated rig should not depend on objects provided this way.

def register():
    print("Registered")

def unregister():
    print("Unregistered")

Feature sets are loaded as sub-packages of the rigify.feature_sets placeholder package.

If you need to import modules from another feature set, you should look it up using the same "link" value you declared in "dependencies", using code similar to this:

target_set_root = rigify.feature_set_list.get_module_by_link_safe("https://github.com/other-repository/link")
target_module = importlib.import_module(".rigs.feature.rig_type", target_set_root.__name__)

This should provide resiliency to e.g. GitHub zip download including the branch name in the directory name. Such imports should not be triggered by importing the root __init__.py file of the feature set, because that is necessary to build the link to feature set mapping itself.