diff --git a/rigify/metarigs/human.py b/rigify/metarigs/human.py
index a2524c3f412caf32ff7ca8eae26309a43bb00bab..e4eb9f2bf617019d731024d0cc2c3020ac04e68e 100644
--- a/rigify/metarigs/human.py
+++ b/rigify/metarigs/human.py
@@ -470,6 +470,8 @@ def create(obj):
     bpy.ops.object.mode_set(mode='OBJECT')
     pbone = obj.pose.bones[bones['hips']]
     pbone.rigify_type = 'spine'
+    pbone.rigify_parameters.add()
+    pbone.rigify_parameters[0].chain_bone_controls = "1, 2, 3"
     pbone.lock_location = (False, False, False)
     pbone.lock_rotation = (False, False, False)
     pbone.lock_rotation_w = False
diff --git a/rigify/rigs/spine.py b/rigify/rigs/spine.py
index 37dda1b1cd75c8b7800b07fc65d7a12f3c1b2438..2b4558f4f5c2b6c7cc919a6b14e170de689033a3 100644
--- a/rigify/rigs/spine.py
+++ b/rigify/rigs/spine.py
@@ -16,23 +16,31 @@
 #
 #======================= END GPL LICENSE BLOCK ========================
 
+""" TODO:
+    - Add parameters for bone transform alphas.
+"""
+
+from math import floor
+
 import bpy
 from mathutils import Vector
 from rigify.utils import MetarigError
-from rigify.utils import copy_bone, flip_bone, put_bone
+from rigify.utils import copy_bone, new_bone, flip_bone, put_bone
 from rigify.utils import connected_children_names
 from rigify.utils import strip_org, make_mechanism_name, make_deformer_name
-from rigify.utils import obj_to_bone, create_circle_widget
+from rigify.utils import obj_to_bone, create_circle_widget, create_compass_widget
 from rna_prop_ui import rna_idprop_ui_prop_get
 
 
 script = """
-hips = "%s"
-ribs = "%s"
-if is_selected([hips, ribs]):
-    layout.prop(pose_bones[ribs], '["pivot_slide"]', text="Pivot Slide (" + ribs + ")", slider=True)
-if is_selected(ribs):
-    layout.prop(pose_bones[ribs], '["isolate"]', text="Isolate Rotation (" + ribs + ")", slider=True)
+main = "%s"
+spine = [%s]
+if is_selected([main]+ spine):
+    layout.prop(pose_bones[main], '["pivot_slide"]', text="Pivot Slide (" + main + ")", slider=True)
+
+for name in spine[1:-1]:
+    if is_selected(name):
+        layout.prop(pose_bones[name], '["auto_rotate"]', text="Auto Rotate (" + name + ")", slider=True)
 """
 
 
@@ -49,6 +57,23 @@ class Rig:
         self.org_bones = [bone_name] + connected_children_names(obj, bone_name)
         self.params = params
 
+        # Collect control bone indices
+        self.control_indices = [0, len(self.org_bones) - 1]
+        temp = self.params.chain_bone_controls.split(",")
+        for i in temp:
+            try:
+                j = int(i) - 1
+            except ValueError:
+                pass
+            else:
+                if (j > 0) and (j < len(self.org_bones)) and (j not in self.control_indices):
+                    self.control_indices += [j]
+        self.control_indices.sort()
+
+        self.pivot_rest = self.params.rest_pivot_slide
+        self.pivot_rest = max(self.pivot_rest, 1.0/len(self.org_bones))
+        self.pivot_rest = min(self.pivot_rest, 1.0-(1.0/len(self.org_bones)))
+
         if len(self.org_bones) <= 1:
             raise MetarigError("RIGIFY ERROR: Bone '%s': input to rig type must be a chain of 2 or more bones." % (strip_org(bone)))
 
@@ -83,215 +108,200 @@ class Rig:
         """ Generate the control rig.
 
         """
-        #---------------------------------
-        # Create the hip and rib controls
         bpy.ops.object.mode_set(mode='EDIT')
-
-        # Copy org bones
-        hip_control = copy_bone(self.obj, self.org_bones[0], strip_org(self.org_bones[0]))
-        rib_control = copy_bone(self.obj, self.org_bones[-1], strip_org(self.org_bones[-1]))
-        rib_mch = copy_bone(self.obj, self.org_bones[-1], make_mechanism_name(strip_org(self.org_bones[-1] + ".follow")))
-        hinge = copy_bone(self.obj, self.org_bones[0], make_mechanism_name(strip_org(self.org_bones[-1]) + ".hinge"))
-
         eb = self.obj.data.edit_bones
+        #-------------------------
+        # Get rest slide position
+        a = self.pivot_rest * len(self.org_bones)
+        i = floor(a)
+        a -= i
+        if i == len(self.org_bones):
+            i -= 1
+            a = 1.0
+
+        pivot_rest_pos = eb[self.org_bones[i]].head.copy()
+        pivot_rest_pos += eb[self.org_bones[i]].vector * a
+
+        #----------------------
+        # Create controls
+
+        # Create control bones
+        controls = []
+        for i in self.control_indices:
+            name = copy_bone(self.obj, self.org_bones[i], strip_org(self.org_bones[i]))
+            controls += [name]
+
+        # Create control parents
+        control_parents = []
+        for i in self.control_indices[1:-1]:
+            name = new_bone(self.obj, make_mechanism_name("par_" + strip_org(self.org_bones[i])))
+            control_parents += [name]
+
+        # Create sub-control bones
+        subcontrols = []
+        for i in self.control_indices:
+            name = new_bone(self.obj, make_mechanism_name("sub_" + strip_org(self.org_bones[i])))
+            subcontrols += [name]
+
+        # Create main control bone
+        main_control = new_bone(self.obj, self.params.spine_main_control_name)
+
+        # Create main control WGT bones
+        main_wgt1 = new_bone(self.obj, make_mechanism_name(self.params.spine_main_control_name + ".01"))
+        main_wgt2 = new_bone(self.obj, make_mechanism_name(self.params.spine_main_control_name + ".02"))
 
-        hip_control_e = eb[hip_control]
-        rib_control_e = eb[rib_control]
-        rib_mch_e = eb[rib_mch]
-        hinge_e = eb[hinge]
-
-        # Parenting
-        hip_control_e.use_connect = False
-        rib_control_e.use_connect = False
-        rib_mch_e.use_connect = False
-        hinge_e.use_connect = False
-
-        hinge_e.parent = None
-        rib_control_e.parent = hinge_e
-        rib_mch_e.parent = rib_control_e
-
-        # Position
-        flip_bone(self.obj, hip_control)
-        flip_bone(self.obj, hinge)
-
-        hinge_e.length /= 2
-        rib_mch_e.length /= 2
-
-        put_bone(self.obj, rib_control, hip_control_e.head)
-        put_bone(self.obj, rib_mch, hip_control_e.head)
-
-        bpy.ops.object.mode_set(mode='POSE')
-        bpy.ops.object.mode_set(mode='EDIT')
         eb = self.obj.data.edit_bones
 
-        # Switch to object mode
+        # Parent the main control
+        eb[main_control].use_connect = False
+        eb[main_control].parent = eb[self.org_bones[0]].parent
+
+        # Parent the main WGTs
+        eb[main_wgt1].use_connect = False
+        eb[main_wgt1].parent = eb[main_control]
+        eb[main_wgt2].use_connect = False
+        eb[main_wgt2].parent = eb[main_wgt1]
+
+        # Parent the controls and sub-controls
+        for name, subname in zip(controls, subcontrols):
+            eb[name].use_connect = False
+            eb[name].parent = eb[main_control]
+            eb[subname].use_connect = False
+            eb[subname].parent = eb[name]
+
+        # Parent the control parents
+        for name, par_name in zip(controls[1:-1], control_parents):
+            eb[par_name].use_connect = False
+            eb[par_name].parent = eb[main_control]
+            eb[name].parent = eb[par_name]
+
+        # Position the main bone
+        put_bone(self.obj, main_control, pivot_rest_pos)
+        eb[main_control].length = sum([eb[b].length for b in self.org_bones]) / 2
+
+        # Position the main WGTs
+        eb[main_wgt1].tail = (0.0, 0.0, sum([eb[b].length for b in self.org_bones]) / 4)
+        eb[main_wgt2].length = sum([eb[b].length for b in self.org_bones]) / 4
+        put_bone(self.obj, main_wgt1, pivot_rest_pos)
+        put_bone(self.obj, main_wgt2, pivot_rest_pos)
+
+        # Position the controls and sub-controls
+        pos = eb[controls[0]].head.copy()
+        for name, subname in zip(controls, subcontrols):
+            put_bone(self.obj, name, pivot_rest_pos)
+            put_bone(self.obj, subname, pivot_rest_pos)
+            eb[subname].length = eb[name].length / 3
+
+        # Position the control parents
+        for name, par_name in zip(controls[1:-1], control_parents):
+            put_bone(self.obj, par_name, pivot_rest_pos)
+            eb[par_name].length = eb[name].length / 2
+
+        #-----------------------------------------
+        # Control bone constraints and properties
         bpy.ops.object.mode_set(mode='OBJECT')
         pb = self.obj.pose.bones
-        hip_control_p = pb[hip_control]
-        rib_control_p = pb[rib_control]
-        hinge_p = pb[hinge]
 
-        # No translation on rib control
-        rib_control_p.lock_location = [True, True, True]
-
-        # Hip does not use local location
-        hip_control_p.bone.use_local_location = False
-
-        # Custom hinge property
-        prop = rna_idprop_ui_prop_get(rib_control_p, "isolate", create=True)
-        rib_control_p["isolate"] = 1.0
-        prop["soft_min"] = prop["min"] = 0.0
-        prop["soft_max"] = prop["max"] = 1.0
+        # Lock control locations
+        for name in controls:
+            bone = pb[name]
+            bone.lock_location = True, True, True
+
+        # Main control doesn't use local location
+        pb[main_control].bone.use_local_location = False
+
+        
+
+        # Intermediate controls follow hips and spine
+        for name, par_name, i in zip(controls[1:-1], control_parents, self.control_indices[1:-1]):
+            bone = pb[par_name]
+
+            # Custom bend_alpha property
+            prop = rna_idprop_ui_prop_get(pb[name], "bend_alpha", create=True)
+            pb[name]["bend_alpha"] = i / (len(self.org_bones) - 1)  # set bend alpha
+            prop["min"] = 0.0
+            prop["max"] = 1.0
+            prop["soft_min"] = 0.0
+            prop["soft_max"] = 1.0
+
+            # Custom auto_rotate
+            prop = rna_idprop_ui_prop_get(pb[name], "auto_rotate", create=True)
+            pb[name]["auto_rotate"] = 1.0
+            prop["min"] = 0.0
+            prop["max"] = 1.0
+            prop["soft_min"] = 0.0
+            prop["soft_max"] = 1.0
+
+            # Constraints
+            con1 = bone.constraints.new('COPY_TRANSFORMS')
+            con1.name = "copy_transforms"
+            con1.target = self.obj
+            con1.subtarget = subcontrols[0]
+
+            con2 = bone.constraints.new('COPY_TRANSFORMS')
+            con2.name = "copy_transforms"
+            con2.target = self.obj
+            con2.subtarget = subcontrols[-1]
+
+            # Drivers
+            fcurve = con1.driver_add("influence")
+            driver = fcurve.driver
+            driver.type = 'AVERAGE'
+            var = driver.variables.new()
+            var.name = "auto"
+            var.targets[0].id_type = 'OBJECT'
+            var.targets[0].id = self.obj
+            var.targets[0].data_path = pb[name].path_from_id() + '["auto_rotate"]'
 
-        # Constraints
-        con = hinge_p.constraints.new('COPY_LOCATION')
-        con.name = "copy_location"
-        con.target = self.obj
-        con.subtarget = hip_control
-
-        con1 = hinge_p.constraints.new('COPY_ROTATION')
-        con1.name = "isolate_off.01"
-        con1.target = self.obj
-        con1.subtarget = hip_control
-
-        con2 = rib_control_p.constraints.new('COPY_SCALE')
-        con2.name = "isolate_off.02"
-        con2.target = self.obj
-        con2.subtarget = hip_control
-        con2.use_offset = True
-        con2.target_space = 'LOCAL'
-        con2.owner_space = 'LOCAL'
-
-        # Drivers for "isolate_off"
-        fcurve = con1.driver_add("influence")
-        driver = fcurve.driver
-        var = driver.variables.new()
-        driver.type = 'AVERAGE'
-        var.name = "var"
-        var.targets[0].id_type = 'OBJECT'
-        var.targets[0].id = self.obj
-        var.targets[0].data_path = rib_control_p.path_from_id() + '["isolate"]'
-        mod = fcurve.modifiers[0]
-        mod.poly_order = 1
-        mod.coefficients[0] = 1.0
-        mod.coefficients[1] = -1.0
-
-        fcurve = con2.driver_add("influence")
-        driver = fcurve.driver
-        var = driver.variables.new()
-        driver.type = 'AVERAGE'
-        var.name = "var"
-        var.targets[0].id_type = 'OBJECT'
-        var.targets[0].id = self.obj
-        var.targets[0].data_path = rib_control_p.path_from_id() + '["isolate"]'
-        mod = fcurve.modifiers[0]
-        mod.poly_order = 1
-        mod.coefficients[0] = 1.0
-        mod.coefficients[1] = -1.0
-
-        # Appearence
-        hip_control_p.custom_shape_transform = pb[self.org_bones[0]]
-        rib_control_p.custom_shape_transform = pb[self.org_bones[-1]]
+            fcurve = con2.driver_add("influence")
+            driver = fcurve.driver
+            driver.type = 'SCRIPTED'
+            driver.expression = "alpha * auto"
+            var = driver.variables.new()
+            var.name = "alpha"
+            var.targets[0].id_type = 'OBJECT'
+            var.targets[0].id = self.obj
+            var.targets[0].data_path = pb[name].path_from_id() + '["bend_alpha"]'
+            var = driver.variables.new()
+            var.name = "auto"
+            var.targets[0].id_type = 'OBJECT'
+            var.targets[0].id = self.obj
+            var.targets[0].data_path = pb[name].path_from_id() + '["auto_rotate"]'
 
         #-------------------------
         # Create flex spine chain
-
-        # Create bones/parenting/positiong
         bpy.ops.object.mode_set(mode='EDIT')
         flex_bones = []
-        flex_helpers = []
+        flex_subs = []
         prev_bone = None
         for b in self.org_bones:
             # Create bones
             bone = copy_bone(self.obj, b, make_mechanism_name(strip_org(b) + ".flex"))
-            helper = copy_bone(self.obj, rib_mch, make_mechanism_name(strip_org(b) + ".flex_h"))
+            sub = new_bone(self.obj, make_mechanism_name(strip_org(b) + ".flex_s"))
             flex_bones += [bone]
-            flex_helpers += [helper]
+            flex_subs += [sub]
 
             eb = self.obj.data.edit_bones
             bone_e = eb[bone]
-            helper_e = eb[helper]
+            sub_e = eb[sub]
 
             # Parenting
             bone_e.use_connect = False
-            helper_e.use_connect = False
+            sub_e.use_connect = False
             if prev_bone is None:
-                helper_e.parent = eb[hip_control]
-            bone_e.parent = helper_e
+                sub_e.parent = eb[controls[0]]
+            else:
+                sub_e.parent = eb[prev_bone]
+            bone_e.parent = sub_e
 
             # Position
-            put_bone(self.obj, helper, bone_e.head)
-            helper_e.length /= 4
+            put_bone(self.obj, sub, bone_e.head)
+            sub_e.length /= 4
+            if prev_bone is not None:
+                sub_e.use_connect = True
 
             prev_bone = bone
 
-        # Constraints
-        bpy.ops.object.mode_set(mode='OBJECT')
-        pb = self.obj.pose.bones
-        rib_control_p = pb[rib_control]
-        rib_mch_p = pb[rib_mch]
-
-        inc = 1.0 / (len(flex_helpers) - 1)
-        inf = 1.0 / (len(flex_helpers) - 1)
-        for b in zip(flex_helpers[1:], flex_bones[:-1], self.org_bones[1:]):
-            bone_p = pb[b[0]]
-
-            # Scale constraints
-            con = bone_p.constraints.new('COPY_SCALE')
-            con.name = "copy_scale1"
-            con.target = self.obj
-            con.subtarget = flex_helpers[0]
-            con.influence = 1.0
-
-            con = bone_p.constraints.new('COPY_SCALE')
-            con.name = "copy_scale2"
-            con.target = self.obj
-            con.subtarget = rib_mch
-            con.influence = inf
-
-            # Bend constraints
-            con = bone_p.constraints.new('COPY_ROTATION')
-            con.name = "bend1"
-            con.target = self.obj
-            con.subtarget = flex_helpers[0]
-            con.influence = 1.0
-
-            con = bone_p.constraints.new('COPY_ROTATION')
-            con.name = "bend2"
-            con.target = self.obj
-            con.subtarget = rib_mch
-            con.influence = inf
-
-            # If not the rib control
-            if b[0] != flex_helpers[-1]:
-                # Custom bend property
-                prop_name = "bend_" + strip_org(b[2])
-                prop = rna_idprop_ui_prop_get(rib_control_p, prop_name, create=True)
-                rib_control_p[prop_name] = inf
-                prop["min"] = 0.0
-                prop["max"] = 1.0
-                prop["soft_min"] = 0.0
-                prop["soft_max"] = 1.0
-
-                # Bend driver
-                fcurve = con.driver_add("influence")
-                driver = fcurve.driver
-                var = driver.variables.new()
-                driver.type = 'AVERAGE'
-                var.name = prop_name
-                var.targets[0].id_type = 'OBJECT'
-                var.targets[0].id = self.obj
-                var.targets[0].data_path = rib_control_p.path_from_id() + '["' + prop_name + '"]'
-
-            # Location constraint
-            con = bone_p.constraints.new('COPY_LOCATION')
-            con.name = "copy_location"
-            con.target = self.obj
-            con.subtarget = b[1]
-            con.head_tail = 1.0
-
-            inf += inc
-
         #----------------------------
         # Create reverse spine chain
 
@@ -315,7 +325,7 @@ class Rig:
             bone_e.tail = Vector(eb[b[0]].head)
             #bone_e.head = Vector(eb[b[0]].tail)
             if prev_bone is None:
-                pass  # Position base bone wherever you want, for now do nothing (i.e. position at hips)
+                put_bone(self.obj, bone, pivot_rest_pos)
             else:
                 put_bone(self.obj, bone, eb[prev_bone].tail)
 
@@ -332,41 +342,48 @@ class Rig:
             con.name = "copy_location"
             con.target = self.obj
             if prev_bone is None:
-                con.subtarget = hip_control  # Position base bone wherever you want, for now hips
+                con.subtarget = main_control
             else:
                 con.subtarget = prev_bone
                 con.head_tail = 1.0
             prev_bone = bone
 
-        #---------------------------------------------
-        # Constrain org bones to flex bone's rotation
+        #----------------------------------------
+        # Constrain original bones to flex spine
+        bpy.ops.object.mode_set(mode='OBJECT')
         pb = self.obj.pose.bones
-        for b in zip(self.org_bones, flex_bones):
-            con = pb[b[0]].constraints.new('COPY_TRANSFORMS')
-            con.name = "copy_rotation"
+
+        for obone, fbone in zip(self.org_bones, flex_bones):
+            con = pb[obone].constraints.new('COPY_TRANSFORMS')
+            con.name = "copy_transforms"
             con.target = self.obj
-            con.subtarget = b[1]
+            con.subtarget = fbone
 
         #---------------------------
         # Create pivot slide system
         pb = self.obj.pose.bones
         bone_p = pb[self.org_bones[0]]
-        rib_control_p = pb[rib_control]
+        main_control_p = pb[main_control]
 
         # Custom pivot_slide property
-        prop = rna_idprop_ui_prop_get(rib_control_p, "pivot_slide", create=True)
-        rib_control_p["pivot_slide"] = 1.0 / len(self.org_bones)
+        prop = rna_idprop_ui_prop_get(main_control_p, "pivot_slide", create=True)
+        main_control_p["pivot_slide"] = self.pivot_rest
         prop["min"] = 0.0
         prop["max"] = 1.0
         prop["soft_min"] = 1.0 / len(self.org_bones)
         prop["soft_max"] = 1.0 - (1.0 / len(self.org_bones))
 
-        # Anchor constraint
+        # Anchor constraints
         con = bone_p.constraints.new('COPY_LOCATION')
         con.name = "copy_location"
         con.target = self.obj
         con.subtarget = rev_bones[0]
 
+        con = pb[main_wgt1].constraints.new('COPY_ROTATION')
+        con.name = "copy_rotation"
+        con.target = self.obj
+        con.subtarget = rev_bones[0]
+
         # Slide constraints
         i = 1
         tot = len(rev_bones)
@@ -385,25 +402,113 @@ class Rig:
             var.name = "slide"
             var.targets[0].id_type = 'OBJECT'
             var.targets[0].id = self.obj
-            var.targets[0].data_path = rib_control_p.path_from_id() + '["pivot_slide"]'
+            var.targets[0].data_path = main_control_p.path_from_id() + '["pivot_slide"]'
             mod = fcurve.modifiers[0]
             mod.poly_order = 1
             mod.coefficients[0] = 1 - i
             mod.coefficients[1] = tot
 
+            # Main WGT
+            con = pb[main_wgt1].constraints.new('COPY_ROTATION')
+            con.name = "slide." + str(i)
+            con.target = self.obj
+            con.subtarget = rb
+
+            # Driver
+            fcurve = con.driver_add("influence")
+            driver = fcurve.driver
+            var = driver.variables.new()
+            driver.type = 'AVERAGE'
+            var.name = "slide"
+            var.targets[0].id_type = 'OBJECT'
+            var.targets[0].id = self.obj
+            var.targets[0].data_path = main_control_p.path_from_id() + '["pivot_slide"]'
+            mod = fcurve.modifiers[0]
+            mod.poly_order = 1
+            mod.coefficients[0] = 1.5 - i
+            mod.coefficients[1] = tot
+
             i += 1
 
+        #----------------------------------
+        # Constrain flex spine to controls
+        bpy.ops.object.mode_set(mode='OBJECT')
+        pb = self.obj.pose.bones
+
+        # Constrain the bones that correspond exactly to the controls
+        for i, name in zip(self.control_indices, subcontrols):
+            con = pb[flex_subs[i]].constraints.new('COPY_TRANSFORMS')
+            con.name = "copy_transforms"
+            con.target = self.obj
+            con.subtarget = name
+
+        # Constrain the bones in-between the controls
+        for i, j, name1, name2 in zip(self.control_indices, self.control_indices[1:], subcontrols, subcontrols[1:]):
+            if (i + 1) < j:
+                for n in range(i + 1, j):
+                    bone = pb[flex_subs[n]]
+                    # Custom bend_alpha property
+                    prop = rna_idprop_ui_prop_get(bone, "bend_alpha", create=True)
+                    bone["bend_alpha"] = (n - i) / (j - i)  # set bend alpha
+                    prop["min"] = 0.0
+                    prop["max"] = 1.0
+                    prop["soft_min"] = 0.0
+                    prop["soft_max"] = 1.0
+
+                    con = bone.constraints.new('COPY_TRANSFORMS')
+                    con.name = "copy_transforms"
+                    con.target = self.obj
+                    con.subtarget = name1
+
+                    con = bone.constraints.new('COPY_TRANSFORMS')
+                    con.name = "copy_transforms"
+                    con.target = self.obj
+                    con.subtarget = name2
+
+                    # Driver
+                    fcurve = con.driver_add("influence")
+                    driver = fcurve.driver
+                    var = driver.variables.new()
+                    driver.type = 'AVERAGE'
+                    var.name = "alpha"
+                    var.targets[0].id_type = 'OBJECT'
+                    var.targets[0].id = self.obj
+                    var.targets[0].data_path = bone.path_from_id() + '["bend_alpha"]'
+
+        #-------------
+        # Final stuff
+        bpy.ops.object.mode_set(mode='OBJECT')
+        pb = self.obj.pose.bones
+
+        # Control appearance
+        # Main
+        pb[main_control].custom_shape_transform = pb[main_wgt2]
+        w = create_compass_widget(self.obj, main_control)
+        if w != None:
+            obj_to_bone(w, self.obj, main_wgt2)
+
+        # Spines
+        for name, i in zip(controls[1:-1], self.control_indices[1:-1]):
+            pb[name].custom_shape_transform = pb[self.org_bones[i]]
+            # Create control widgets
+            w = create_circle_widget(self.obj, name, radius=1.0, head_tail=0.5, with_line=True)
+            if w != None:
+                obj_to_bone(w, self.obj, self.org_bones[i])
+        # Hips
+        pb[controls[0]].custom_shape_transform = pb[self.org_bones[0]]
         # Create control widgets
-        w1 = create_circle_widget(self.obj, hip_control, radius=1.0, head_tail=1.0)
-        w2 = create_circle_widget(self.obj, rib_control, radius=1.0, head_tail=0.0)
+        w = create_circle_widget(self.obj, controls[0], radius=1.0, head_tail=0.5, with_line=True)
+        if w != None:
+            obj_to_bone(w, self.obj, self.org_bones[0])
 
-        if w1 != None:
-            obj_to_bone(w1, self.obj, self.org_bones[0])
-        if w2 != None:
-            obj_to_bone(w2, self.obj, self.org_bones[-1])
+        # Ribs
+        pb[controls[-1]].custom_shape_transform = pb[self.org_bones[-1]]
+        # Create control widgets
+        w = create_circle_widget(self.obj, controls[-1], radius=1.0, head_tail=0.5, with_line=True)
+        if w != None:
+            obj_to_bone(w, self.obj, self.org_bones[-1])
 
-        # Return control names
-        return hip_control, rib_control
+        return [main_control] + controls
 
     def generate(self):
         """ Generate the rig.
@@ -412,9 +517,35 @@ class Rig:
 
         """
         self.gen_deform()
-        hips, ribs = self.gen_control()
+        controls = self.gen_control()
+
+        controls_string = ", ".join(["'" + x + "'" for x in controls[1:]])
+        return [script % (controls[0], controls_string)]
+
+    @classmethod
+    def add_parameters(self, group):
+        """ Add the parameters of this rig type to the
+            RigifyParameters PropertyGroup
+        """
+        group.spine_main_control_name = bpy.props.StringProperty(name="Main control name", default="torso", description="Name that the main control bone should be given.")
+        group.rest_pivot_slide = bpy.props.FloatProperty(name="Rest Pivot Slide", default=0.0, min=0.0, max=1.0, soft_min=0.0, soft_max=1.0, description="The pivot slide value in the rest pose.")
+        group.chain_bone_controls = bpy.props.StringProperty(name="Control bone list", default="", description="Define which bones have controls.")
+
 
-        return [script % (hips, ribs)]
+    @classmethod
+    def parameters_ui(self, layout, obj, bone):
+        """ Create the ui for the rig parameters.
+        """
+        params = obj.pose.bones[bone].rigify_parameters[0]
+
+        r = layout.row()
+        r.prop(params, "spine_main_control_name")
+
+        r = layout.row()
+        r.prop(params, "rest_pivot_slide", slider=True)
+
+        r = layout.row()
+        r.prop(params, "chain_bone_controls")
 
     @classmethod
     def create_sample(self, obj):
@@ -469,6 +600,8 @@ class Rig:
         pbone.rotation_mode = 'QUATERNION'
         pbone = obj.pose.bones[bones['hips']]
         pbone['rigify_type'] = 'spine'
+        pbone.rigify_parameters.add()
+        pbone.rigify_parameters[0].chain_bone_controls = "1, 2, 3"
 
         bpy.ops.object.mode_set(mode='EDIT')
         for bone in arm.edit_bones:
@@ -481,4 +614,3 @@ class Rig:
             bone.select_head = True
             bone.select_tail = True
             arm.edit_bones.active = bone
-
diff --git a/rigify/utils.py b/rigify/utils.py
index 193a2779a36982d5e1dc8c15df837faae1bfd4b2..c97712228b03d0dc52c5eaed9c8f6a133bd6dadf 100644
--- a/rigify/utils.py
+++ b/rigify/utils.py
@@ -279,7 +279,7 @@ def create_line_widget(rig, bone_name):
         mesh.update()
 
 
-def create_circle_widget(rig, bone_name, radius=1.0, head_tail=0.0):
+def create_circle_widget(rig, bone_name, radius=1.0, head_tail=0.0, with_line=False):
     """ Creates a basic circle widget, a circle around the y-axis.
         radius: the radius of the circle
         head_tail: where along the length of the bone the circle is (0.0=head, 1.0=tail)
@@ -288,7 +288,10 @@ def create_circle_widget(rig, bone_name, radius=1.0, head_tail=0.0):
     if obj != None:
         v = [(0.7071068286895752, 2.980232238769531e-07, -0.7071065306663513), (0.8314696550369263, 2.980232238769531e-07, -0.5555699467658997), (0.9238795042037964, 2.682209014892578e-07, -0.3826831877231598), (0.9807852506637573, 2.5331974029541016e-07, -0.19509011507034302), (1.0, 2.365559055306221e-07, 1.6105803979371558e-07), (0.9807853698730469, 2.2351741790771484e-07, 0.19509044289588928), (0.9238796234130859, 2.086162567138672e-07, 0.38268351554870605), (0.8314696550369263, 1.7881393432617188e-07, 0.5555704236030579), (0.7071068286895752, 1.7881393432617188e-07, 0.7071070075035095), (0.5555702447891235, 1.7881393432617188e-07, 0.8314698934555054), (0.38268327713012695, 1.7881393432617188e-07, 0.923879861831665), (0.19509008526802063, 1.7881393432617188e-07, 0.9807855486869812), (-3.2584136988589307e-07, 1.1920928955078125e-07, 1.000000238418579), (-0.19509072601795197, 1.7881393432617188e-07, 0.9807854294776917), (-0.3826838731765747, 1.7881393432617188e-07, 0.9238795638084412), (-0.5555707216262817, 1.7881393432617188e-07, 0.8314695358276367), (-0.7071071863174438, 1.7881393432617188e-07, 0.7071065902709961), (-0.8314700126647949, 1.7881393432617188e-07, 0.5555698871612549), (-0.923879861831665, 2.086162567138672e-07, 0.3826829195022583), (-0.9807853698730469, 2.2351741790771484e-07, 0.1950896978378296), (-1.0, 2.365559907957504e-07, -7.290432222362142e-07), (-0.9807850122451782, 2.5331974029541016e-07, -0.195091113448143), (-0.9238790273666382, 2.682209014892578e-07, -0.38268423080444336), (-0.831468939781189, 2.980232238769531e-07, -0.5555710196495056), (-0.7071058750152588, 2.980232238769531e-07, -0.707107424736023), (-0.555569052696228, 2.980232238769531e-07, -0.8314701318740845), (-0.38268208503723145, 2.980232238769531e-07, -0.923879861831665), (-0.19508881866931915, 2.980232238769531e-07, -0.9807853102684021), (1.6053570561780361e-06, 2.980232238769531e-07, -0.9999997615814209), (0.19509197771549225, 2.980232238769531e-07, -0.9807847142219543), (0.3826850652694702, 2.980232238769531e-07, -0.9238786101341248), (0.5555717945098877, 2.980232238769531e-07, -0.8314683437347412)]
         verts = [(a[0] * radius, head_tail, a[2] * radius) for a in v]
-        edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (13, 14), (14, 15), (15, 16), (16, 17), (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (22, 23), (23, 24), (24, 25), (25, 26), (26, 27), (27, 28), (28, 29), (29, 30), (30, 31), (0, 31)]
+        if with_line:
+            edges = [(28, 12), (0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (13, 14), (14, 15), (15, 16), (16, 17), (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (22, 23), (23, 24), (24, 25), (25, 26), (26, 27), (27, 28), (28, 29), (29, 30), (30, 31), (0, 31)]
+        else:
+            edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (13, 14), (14, 15), (15, 16), (16, 17), (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (22, 23), (23, 24), (24, 25), (25, 26), (26, 27), (27, 28), (28, 29), (29, 30), (30, 31), (0, 31)]
         mesh = obj.data
         mesh.from_pydata(verts, edges, [])
         mesh.update()
@@ -334,6 +337,17 @@ def create_bone_widget(rig, bone_name):
         mesh.update()
 
 
+def create_compass_widget(rig, bone_name):
+    """ Creates a compass-shaped widget.
+    """
+    obj = create_widget(rig, bone_name)
+    if obj != None:
+        verts = [(0.0, 1.2000000476837158, 0.0), (0.19509032368659973, 0.9807852506637573, 0.0), (0.3826834559440613, 0.9238795042037964, 0.0), (0.5555702447891235, 0.8314695954322815, 0.0), (0.7071067690849304, 0.7071067690849304, 0.0), (0.8314696550369263, 0.5555701851844788, 0.0), (0.9238795042037964, 0.3826834261417389, 0.0), (0.9807852506637573, 0.19509035348892212, 0.0), (1.2000000476837158, 7.549790126404332e-08, 0.0), (0.9807853102684021, -0.19509020447731018, 0.0), (0.9238795638084412, -0.38268327713012695, 0.0), (0.8314696550369263, -0.5555701851844788, 0.0), (0.7071067690849304, -0.7071067690849304, 0.0), (0.5555701851844788, -0.8314696550369263, 0.0), (0.38268327713012695, -0.9238796234130859, 0.0), (0.19509008526802063, -0.9807853102684021, 0.0), (-3.2584136988589307e-07, -1.2999999523162842, 0.0), (-0.19509072601795197, -0.9807851910591125, 0.0), (-0.3826838731765747, -0.9238793253898621, 0.0), (-0.5555707216262817, -0.8314692974090576, 0.0), (-0.7071072459220886, -0.707106351852417, 0.0), (-0.8314700126647949, -0.5555696487426758, 0.0), (-0.923879861831665, -0.3826826810836792, 0.0), (-0.9807854294776917, -0.1950894594192505, 0.0), (-1.2000000476837158, 9.655991561885457e-07, 0.0), (-0.980785071849823, 0.1950913518667221, 0.0), (-0.923879086971283, 0.38268446922302246, 0.0), (-0.831468939781189, 0.5555712580680847, 0.0), (-0.7071058750152588, 0.707107663154602, 0.0), (-0.5555691123008728, 0.8314703702926636, 0.0), (-0.38268208503723145, 0.9238801002502441, 0.0), (-0.19508881866931915, 0.9807855486869812, 0.0)]
+        edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (13, 14), (14, 15), (15, 16), (16, 17), (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (22, 23), (23, 24), (24, 25), (25, 26), (26, 27), (27, 28), (28, 29), (29, 30), (30, 31), (0, 31)]
+        mesh = obj.data
+        mesh.from_pydata(verts, edges, [])
+        mesh.update()
+
 def create_root_widget(rig, bone_name):
     """ Creates a widget for the root bone.
     """