[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [1213] trunk/py/scripts/addons/rigify/ README: Added a readme file that gives a brief explanation of the internals of Rigify

Nathan Vegdahl cessen at cessen.com
Thu Dec 2 02:52:04 CET 2010


Revision: 1213
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-extensions&revision=1213
Author:   cessen
Date:     2010-12-02 02:52:04 +0100 (Thu, 02 Dec 2010)

Log Message:
-----------
Added a readme file that gives a brief explanation of the internals of Rigify
and how to write your own rig types.

Added Paths:
-----------
    trunk/py/scripts/addons/rigify/README

Added: trunk/py/scripts/addons/rigify/README
===================================================================
--- trunk/py/scripts/addons/rigify/README	                        (rev 0)
+++ trunk/py/scripts/addons/rigify/README	2010-12-02 01:52:04 UTC (rev 1213)
@@ -0,0 +1,238 @@
+INTRODUCTION
+------------
+Rigify is an auto-rigging system based on a "building blocks" paradigm.  The
+user can create a rig by putting together any combination of rig types, in any
+confguration that they want.
+
+A rig type is something like "biped arm" or "spine" or "finger".
+
+The input to the Rigify system is something called a "metarig".  It is an
+armature that contains data about how to construct the rig.  In particular, it
+contains bones in the basic configuration of the rig, with some bones tagged
+to indicate the rig type.
+
+For example, a metaig might contain a chain of three bones, the root-most of
+which is tagged as being a biped arm.  When given as input to Rigify, Rigify
+will then generate a fully-featured biped arm rig in the same position and
+proportions as the 3-bone chain.
+
+One could also have another chain of bones, the root-most of which is tagged as
+being a spine.  And the root-most bone of the arm chain could be the child of
+any of those spine bones.  Then the rig that Rigify would generate would be a
+spine rig with an arm rig attached to it.
+
+
+THE GUTS OF RIGIFY, SUMMARIZED
+------------------------------
+The concept behind rigify is fairly simple.  It recieves an armature as input
+with some of the bones tagged as being certain rig types (arm, leg, etc.)
+
+When Rigify recieves that armature as input, the first thing it does is
+duplicate the armature.  From here on out, the original armature is totally
+ignored.  Only the duplicate is used.  And this duplicate armature object will
+become the generated rig.
+
+Rigify next prepends "ORG-" to all of the bones.  These are the "original"
+bones of the metarig, and they are used as the glue between rig types, as I
+will explain later.
+
+Rigify then generates the rig in two passes.  The first pass is the
+"information gathering" stage.
+
+The information gathering stage doesn't modify the armature at all.  It simply
+gathers information about it.  Or, rather, it lets the rig types gather
+information about it.
+It traverses the bones in a root-most to leaf-most order, and whenever it
+stumbles upon a bone that has a rig type tagged on it, it creates a rig-type
+python object (rig types will be explained further down) for that rig type,
+and executes the resulting object's information gathering code.
+
+At the end of the information gathering stage, Rigify has a collection of
+python objects, each of which know all the information they need to generate
+their own bit of the rig.
+
+The next stage is the rig generation stage.  This part is pretty simple.  All
+Rigify does is it loops over all of the rig-type python objects that it created
+in the previous stage (also in root-most to leaf-most order), and executes
+their rig-generate code.  All of the actual rig generation happens in the
+rig-type python objects.
+
+And that's pretty much it.  As you can see, most of the important code is
+actually in the rig types themselves, not in Rigify.  Rigify is pretty sparse
+when it comes right down to it.
+
+There is one final stage to rig generation.  Rigify checks all of the bones
+for "DEF-", "MCH-", and "ORG-" prefixes, and moves those bones to their own
+layers. It also sets all of the "DEF-" bones to deform, and sets all other
+bones to _not_ deform.  And finally, it looks for any bone that does not have
+a parent, and sets the root bone (which Rigify creates) as their parent.
+
+
+THE GUTS OF A RIG TYPE, BASIC
+-----------------------------
+A rig type is simply a python module containing a class named "Rig".  The Rig
+class is only required to have two methods: __init__() and generate()
+
+__init__() is the "information gathering" code for the rig type.  When Rigify
+loops through the bones and finds a tagged bone, it will create a python
+object from the Rig class, executing this method.
+In addition to the default "self" parameter, __init__() needs to take the
+armature object, the name of the bone that was tagged, and the bone's rig type
+parameters object.
+
+A proper rig-type __init__() will look like this:
+
+    def __init__(self, obj, bone, params):
+        # code goes here
+
+At the bare minimum, you are going to want to store the object and bone name
+in the rig type object for later reference in the generate method.  So:
+
+    def __init__(self, obj, bone, params):
+        self.obj = obj
+        self.org_bone = bone
+
+Most rig types involve more than just that one bone, though, so you will also
+want to store the names of any other relevant bones.  For example, maybe the
+parent of the tagged bone:
+
+    def __init__(self, obj, bone, params):
+        self.obj = obj
+        self.org_bone = bone
+        self.org_parent = obj.data.bones[bone].parent.name
+
+It is important that store the _names_ of the bones, and not direct references.
+Due to how the armature system in Blender works, when flipping in and out of
+edit mode, pose-bone and edit-bone references get lost. (Arg...)
+
+Remember that it is critical that the information-gathering method does _not_
+modify the armature in any way.  This way all of the rig type's info-gathering
+methods can execute on a clean armature.  Many rig types depend on traversing
+parent-child relationships to figure out what bones are relevant to them, for
+example.
+
+
+Next is the generate() method.  This is the method that Rigify calls to
+actually generate the rig.  It takes the form:
+
+    def generate(self):
+        # code goes here
+
+It doesn't take any parameters beyond "self".  So you really need to store any
+information you need with the __init__() method.
+
+Generate pretty much has free reign to do whatever it wants, with the exception
+of two simple rules:
+1. Other than the "ORG-" bones, do not touch anything that is not created by
+this method (this prevents rig types from messing each other up).
+2. Even with "ORG-" bones, the only thing you are allowed to do is add children
+and add constraints.  Do not rename them, do not remove children or
+constraints, and especially do not change their parents.  (Adding constraints
+and adding children are encouraged, though. ;-))  This is because the "ORG-"
+bones are the glue that holds everything together, and changing them beyond
+adding children/constraints ruins the glue, so to speak.
+
+In short: with the exception of adding children/constraints to "ORG-"
+bones, only mess with things that you yourself create.
+
+It is also generally a good idea (though not strictly required) that the rig
+type add constraints to the "ORG-" bones it was generated from so that the
+"ORG-" bones move with the animation controls.
+For example, if I make a simple arm rig type, the controls that the animator
+uses should also move the "ORG-" bones.  That way, any other rig-types that are
+children of those "ORG-" bones will move along with them.  For example, any
+fingers on the end of the arm.
+
+Also, any bones that the animator should not directly animate with should have
+their names prefixed with "DEF-" or "MCH-".  The former if it is a bone that
+is intended to deform the mesh, the latter if it is not.
+It should be obvious, then, that a bone cannot be both an animation control and
+a deforming bone in Rigify.  This is on purpose.
+
+Also note that there are convenience functions in utils.py for prepending
+"DEF-" and "MCH-" to bone names: deformer() and mch()
+There is also a convenience function for stripping "ORG-" from a bone name:
+strip_org()
+Which is useful for removing "ORG-" from bones you create by duplicating
+the "ORG-" bones.
+I recommend you use these functions instead of manually adding/stripping
+these prefixes.  That way if the prefixes are changed, it can be changed in
+one place (those functions) and all the rig types will still work.
+
+
+THE GUTS OF A RIG TYPE, ADVANCED
+--------------------------------
+If you look at any of the rig types included with Rigify, you'll note that they
+have several more methods than just __init__() and generate().
+THESE ADDITIONAL METHODS ARE _NOT_ REQUIRED for a rig type to function.  But
+they can add some nifty functionality to your rig.
+
+Not all of the additional methods you see in the included rig types have any
+special purpose for Rigify, however.  For example, I often create separate
+methods for generating the deformation and control rigs, and then call them
+both from the main generate() method.  But that is just for organization, and
+has nothing to do with Rigify itself.
+
+Here are the additional methods relevant to Rigify, with brief decriptions of
+what they are for:
+
+
+RIG PARAMETERS
+--------------
+For many rig types, it is handy for the user to be able to tweak how they are
+generated.  For example, the included biped arm rig allows the user to specify
+the axis of rotation for the elbow.
+
+There are two methods necessary to give a rig type user-tweakable parameters,
+both of which must be class methods:
+add_parameters()
+parameters_ui()
+
+add_parameters() takes an IDPropertyGroup as input, and adds its parameters
+to that group as RNA properties.  For example:
+
+    @classmethod
+    def add_parameters(self, group):
+        group.toggle_param = bpy.props.BoolProperty(name="Test toggle:", default=False, description="Just a test, not really used for anything.")
+
+parameter_ui() recieves a Blender UILayout object, the metarig object, and the
+tagged bone name.  It creates a GUI in the UILayout for the user to tweak the
+parameters.  For example:
+
+    @classmethod
+    def parameters_ui(self, layout, obj, bone):
+        params = obj.pose.bones[bone].rigify_parameters[0]
+        r = layout.row()
+        r.prop(params, "toggle_param")
+
+
+SAMPLE METARIG
+--------------
+It is a good idea for all rig types to have a sample metarig that the user can
+add to their own metarig.  This is what the create_sample() method is for.
+Like the parameter methods above, create_sample() must be a class method.
+
+create_sample() takes the current armature object as input, and adds the bones
+for its rig-type's metarig.  For example:
+
+    @classmethod
+    def create_sample(self, obj):

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list